io_uring: ensure task_work gets run as part of cancelations
[linux-2.6-microblaze.git] / fs / sysfs / file.c
index d019d6a..42dcf96 100644 (file)
@@ -45,6 +45,9 @@ static int sysfs_kf_seq_show(struct seq_file *sf, void *v)
        ssize_t count;
        char *buf;
 
+       if (WARN_ON_ONCE(!ops->show))
+               return -EINVAL;
+
        /* acquire buffer and ensure that it's >= PAGE_SIZE and clear */
        count = seq_get_buf(sf, &buf);
        if (count < PAGE_SIZE) {
@@ -53,15 +56,9 @@ static int sysfs_kf_seq_show(struct seq_file *sf, void *v)
        }
        memset(buf, 0, PAGE_SIZE);
 
-       /*
-        * Invoke show().  Control may reach here via seq file lseek even
-        * if @ops->show() isn't implemented.
-        */
-       if (ops->show) {
-               count = ops->show(kobj, of->kn->priv, buf);
-               if (count < 0)
-                       return count;
-       }
+       count = ops->show(kobj, of->kn->priv, buf);
+       if (count < 0)
+               return count;
 
        /*
         * The code works fine with PAGE_SIZE return but it's likely to
@@ -255,59 +252,74 @@ static const struct kernfs_ops sysfs_bin_kfops_mmap = {
 };
 
 int sysfs_add_file_mode_ns(struct kernfs_node *parent,
-                          const struct attribute *attr, bool is_bin,
-                          umode_t mode, kuid_t uid, kgid_t gid, const void *ns)
+               const struct attribute *attr, umode_t mode, kuid_t uid,
+               kgid_t gid, const void *ns)
 {
+       struct kobject *kobj = parent->priv;
+       const struct sysfs_ops *sysfs_ops = kobj->ktype->sysfs_ops;
        struct lock_class_key *key = NULL;
-       const struct kernfs_ops *ops;
+       const struct kernfs_ops *ops = NULL;
        struct kernfs_node *kn;
-       loff_t size;
-
-       if (!is_bin) {
-               struct kobject *kobj = parent->priv;
-               const struct sysfs_ops *sysfs_ops = kobj->ktype->sysfs_ops;
-
-               /* every kobject with an attribute needs a ktype assigned */
-               if (WARN(!sysfs_ops, KERN_ERR
-                        "missing sysfs attribute operations for kobject: %s\n",
-                        kobject_name(kobj)))
-                       return -EINVAL;
-
-               if (sysfs_ops->show && sysfs_ops->store) {
-                       if (mode & SYSFS_PREALLOC)
-                               ops = &sysfs_prealloc_kfops_rw;
-                       else
-                               ops = &sysfs_file_kfops_rw;
-               } else if (sysfs_ops->show) {
-                       if (mode & SYSFS_PREALLOC)
-                               ops = &sysfs_prealloc_kfops_ro;
-                       else
-                               ops = &sysfs_file_kfops_ro;
-               } else if (sysfs_ops->store) {
-                       if (mode & SYSFS_PREALLOC)
-                               ops = &sysfs_prealloc_kfops_wo;
-                       else
-                               ops = &sysfs_file_kfops_wo;
-               } else
-                       ops = &sysfs_file_kfops_empty;
-
-               size = PAGE_SIZE;
+
+       /* every kobject with an attribute needs a ktype assigned */
+       if (WARN(!sysfs_ops, KERN_ERR
+                       "missing sysfs attribute operations for kobject: %s\n",
+                       kobject_name(kobj)))
+               return -EINVAL;
+
+       if (mode & SYSFS_PREALLOC) {
+               if (sysfs_ops->show && sysfs_ops->store)
+                       ops = &sysfs_prealloc_kfops_rw;
+               else if (sysfs_ops->show)
+                       ops = &sysfs_prealloc_kfops_ro;
+               else if (sysfs_ops->store)
+                       ops = &sysfs_prealloc_kfops_wo;
        } else {
-               struct bin_attribute *battr = (void *)attr;
-
-               if (battr->mmap)
-                       ops = &sysfs_bin_kfops_mmap;
-               else if (battr->read && battr->write)
-                       ops = &sysfs_bin_kfops_rw;
-               else if (battr->read)
-                       ops = &sysfs_bin_kfops_ro;
-               else if (battr->write)
-                       ops = &sysfs_bin_kfops_wo;
-               else
-                       ops = &sysfs_file_kfops_empty;
-
-               size = battr->size;
+               if (sysfs_ops->show && sysfs_ops->store)
+                       ops = &sysfs_file_kfops_rw;
+               else if (sysfs_ops->show)
+                       ops = &sysfs_file_kfops_ro;
+               else if (sysfs_ops->store)
+                       ops = &sysfs_file_kfops_wo;
+       }
+
+       if (!ops)
+               ops = &sysfs_file_kfops_empty;
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+       if (!attr->ignore_lockdep)
+               key = attr->key ?: (struct lock_class_key *)&attr->skey;
+#endif
+
+       kn = __kernfs_create_file(parent, attr->name, mode & 0777, uid, gid,
+                                 PAGE_SIZE, ops, (void *)attr, ns, key);
+       if (IS_ERR(kn)) {
+               if (PTR_ERR(kn) == -EEXIST)
+                       sysfs_warn_dup(parent, attr->name);
+               return PTR_ERR(kn);
        }
+       return 0;
+}
+
+int sysfs_add_bin_file_mode_ns(struct kernfs_node *parent,
+               const struct bin_attribute *battr, umode_t mode,
+               kuid_t uid, kgid_t gid, const void *ns)
+{
+       const struct attribute *attr = &battr->attr;
+       struct lock_class_key *key = NULL;
+       const struct kernfs_ops *ops;
+       struct kernfs_node *kn;
+
+       if (battr->mmap)
+               ops = &sysfs_bin_kfops_mmap;
+       else if (battr->read && battr->write)
+               ops = &sysfs_bin_kfops_rw;
+       else if (battr->read)
+               ops = &sysfs_bin_kfops_ro;
+       else if (battr->write)
+               ops = &sysfs_bin_kfops_wo;
+       else
+               ops = &sysfs_file_kfops_empty;
 
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
        if (!attr->ignore_lockdep)
@@ -315,7 +327,7 @@ int sysfs_add_file_mode_ns(struct kernfs_node *parent,
 #endif
 
        kn = __kernfs_create_file(parent, attr->name, mode & 0777, uid, gid,
-                                 size, ops, (void *)attr, ns, key);
+                                 battr->size, ops, (void *)attr, ns, key);
        if (IS_ERR(kn)) {
                if (PTR_ERR(kn) == -EEXIST)
                        sysfs_warn_dup(parent, attr->name);
@@ -340,9 +352,7 @@ int sysfs_create_file_ns(struct kobject *kobj, const struct attribute *attr,
                return -EINVAL;
 
        kobject_get_ownership(kobj, &uid, &gid);
-       return sysfs_add_file_mode_ns(kobj->sd, attr, false, attr->mode,
-                                     uid, gid, ns);
-
+       return sysfs_add_file_mode_ns(kobj->sd, attr, attr->mode, uid, gid, ns);
 }
 EXPORT_SYMBOL_GPL(sysfs_create_file_ns);
 
@@ -385,8 +395,8 @@ int sysfs_add_file_to_group(struct kobject *kobj,
                return -ENOENT;
 
        kobject_get_ownership(kobj, &uid, &gid);
-       error = sysfs_add_file_mode_ns(parent, attr, false,
-                                      attr->mode, uid, gid, NULL);
+       error = sysfs_add_file_mode_ns(parent, attr, attr->mode, uid, gid,
+                                      NULL);
        kernfs_put(parent);
 
        return error;
@@ -555,8 +565,8 @@ int sysfs_create_bin_file(struct kobject *kobj,
                return -EINVAL;
 
        kobject_get_ownership(kobj, &uid, &gid);
-       return sysfs_add_file_mode_ns(kobj->sd, &attr->attr, true,
-                                     attr->attr.mode, uid, gid, NULL);
+       return sysfs_add_bin_file_mode_ns(kobj->sd, attr, attr->attr.mode, uid,
+                                          gid, NULL);
 }
 EXPORT_SYMBOL_GPL(sysfs_create_bin_file);