sysfs: split out binary attribute handling from sysfs_add_file_mode_ns
authorChristoph Hellwig <hch@lst.de>
Mon, 13 Sep 2021 05:41:12 +0000 (07:41 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 14 Sep 2021 14:59:46 +0000 (16:59 +0200)
Split adding binary attributes into a separate handler instead of
overloading sysfs_add_file_mode_ns.

Acked-by: Christian Brauner <christian.brauner@ubuntu.com>
Acked-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/r/20210913054121.616001-5-hch@lst.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/sysfs/file.c
fs/sysfs/group.c
fs/sysfs/sysfs.h

index d019d6a..f737bd6 100644 (file)
@@ -255,59 +255,73 @@ 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;
        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;
-       } 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;
+
+       /* 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_empty;
+                       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 = battr->size;
+#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 +329,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 +354,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 +397,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 +567,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);
 
index f29d620..eeb0e30 100644 (file)
@@ -61,8 +61,8 @@ static int create_files(struct kernfs_node *parent, struct kobject *kobj,
                             (*attr)->name, mode);
 
                        mode &= SYSFS_PREALLOC | 0664;
-                       error = sysfs_add_file_mode_ns(parent, *attr, false,
-                                                      mode, uid, gid, NULL);
+                       error = sysfs_add_file_mode_ns(parent, *attr, mode, uid,
+                                                      gid, NULL);
                        if (unlikely(error))
                                break;
                }
@@ -90,10 +90,9 @@ static int create_files(struct kernfs_node *parent, struct kobject *kobj,
                             (*bin_attr)->attr.name, mode);
 
                        mode &= SYSFS_PREALLOC | 0664;
-                       error = sysfs_add_file_mode_ns(parent,
-                                       &(*bin_attr)->attr, true,
-                                       mode,
-                                       uid, gid, NULL);
+                       error = sysfs_add_bin_file_mode_ns(parent, *bin_attr,
+                                                          mode, uid, gid,
+                                                          NULL);
                        if (error)
                                break;
                }
@@ -340,8 +339,8 @@ int sysfs_merge_group(struct kobject *kobj,
        kobject_get_ownership(kobj, &uid, &gid);
 
        for ((i = 0, attr = grp->attrs); *attr && !error; (++i, ++attr))
-               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);
        if (error) {
                while (--i >= 0)
                        kernfs_remove_by_name(parent, (*--attr)->name);
index 0050cc0..3f28c9a 100644 (file)
@@ -28,9 +28,11 @@ void sysfs_warn_dup(struct kernfs_node *parent, const char *name);
  * file.c
  */
 int sysfs_add_file_mode_ns(struct kernfs_node *parent,
-                          const struct attribute *attr, bool is_bin,
-                          umode_t amode, kuid_t uid, kgid_t gid,
-                          const void *ns);
+               const struct attribute *attr, umode_t amode, kuid_t uid,
+               kgid_t gid, const void *ns);
+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);
 
 /*
  * symlink.c