[SCSI] sysfs: add filter function to groups
authorJames Bottomley <James.Bottomley@HansenPartnership.com>
Wed, 31 Oct 2007 14:38:04 +0000 (09:38 -0500)
committerJames Bottomley <James.Bottomley@HansenPartnership.com>
Wed, 23 Jan 2008 17:29:18 +0000 (11:29 -0600)
This patch allows the various users of attribute_groups to selectively
allow the appearance of group attributes.  The primary consumer of
this will be the transport classes in which we currently have
elaborate attribute selection algorithms to do this same thing.

Acked-by: Greg KH <greg@kroah.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
fs/sysfs/group.c
include/linux/sysfs.h
kernel/params.c

index d1972374655a22377e94186b62564aaa83f2299f..0871c3dadce1c4a16d469b9a03b511f3eadbb937 100644 (file)
 #include "sysfs.h"
 
 
-static void remove_files(struct sysfs_dirent *dir_sd,
+static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj,
                         const struct attribute_group *grp)
 {
        struct attribute *const* attr;
+       int i;
 
-       for (attr = grp->attrs; *attr; attr++)
-               sysfs_hash_and_remove(dir_sd, (*attr)->name);
+       for (i = 0, attr = grp->attrs; *attr; i++, attr++)
+               if (!grp->is_visible ||
+                   grp->is_visible(kobj, *attr, i))
+                       sysfs_hash_and_remove(dir_sd, (*attr)->name);
 }
 
-static int create_files(struct sysfs_dirent *dir_sd,
+static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj,
                        const struct attribute_group *grp)
 {
        struct attribute *const* attr;
-       int error = 0;
+       int error = 0, i;
 
-       for (attr = grp->attrs; *attr && !error; attr++)
-               error = sysfs_add_file(dir_sd, *attr, SYSFS_KOBJ_ATTR);
+       for (i = 0, attr = grp->attrs; *attr && !error; i++, attr++)
+               if (!grp->is_visible ||
+                   grp->is_visible(kobj, *attr, i))
+                       error |=
+                               sysfs_add_file(dir_sd, *attr, SYSFS_KOBJ_ATTR);
        if (error)
-               remove_files(dir_sd, grp);
+               remove_files(dir_sd, kobj, grp);
        return error;
 }
 
@@ -54,7 +60,7 @@ int sysfs_create_group(struct kobject * kobj,
        } else
                sd = kobj->sd;
        sysfs_get(sd);
-       error = create_files(sd, grp);
+       error = create_files(sd, kobj, grp);
        if (error) {
                if (grp->name)
                        sysfs_remove_subdir(sd);
@@ -75,7 +81,7 @@ void sysfs_remove_group(struct kobject * kobj,
        } else
                sd = sysfs_get(dir_sd);
 
-       remove_files(sd, grp);
+       remove_files(sd, kobj, grp);
        if (grp->name)
                sysfs_remove_subdir(sd);
 
index 149ab62329e238aab4ce518c41e4070764a8d32d..802710438a9e8a3b548d9549770268cb1ac2316b 100644 (file)
@@ -32,6 +32,8 @@ struct attribute {
 
 struct attribute_group {
        const char              *name;
+       int                     (*is_visible)(struct kobject *,
+                                             struct attribute *, int);
        struct attribute        **attrs;
 };
 
index 7686417ee00eba070b7d9b5c9dd293f9991199f1..dfef46474e55b70f380568ac5592ae35b2f3baa2 100644 (file)
@@ -472,7 +472,7 @@ param_sysfs_setup(struct module_kobject *mk,
                        sizeof(mp->grp.attrs[0]));
        size[1] = (valid_attrs + 1) * sizeof(mp->grp.attrs[0]);
 
-       mp = kmalloc(size[0] + size[1], GFP_KERNEL);
+       mp = kzalloc(size[0] + size[1], GFP_KERNEL);
        if (!mp)
                return ERR_PTR(-ENOMEM);