aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/sysfs/group.c17
-rw-r--r--include/linux/sysfs.h18
2 files changed, 29 insertions, 6 deletions
diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c
index 39a019936768..51b56e6d9537 100644
--- a/fs/sysfs/group.c
+++ b/fs/sysfs/group.c
@@ -73,13 +73,26 @@ static int create_files(struct kernfs_node *parent, struct kobject *kobj,
73 } 73 }
74 74
75 if (grp->bin_attrs) { 75 if (grp->bin_attrs) {
76 for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++) { 76 for (i = 0, bin_attr = grp->bin_attrs; *bin_attr; i++, bin_attr++) {
77 umode_t mode = (*bin_attr)->attr.mode;
78
77 if (update) 79 if (update)
78 kernfs_remove_by_name(parent, 80 kernfs_remove_by_name(parent,
79 (*bin_attr)->attr.name); 81 (*bin_attr)->attr.name);
82 if (grp->is_bin_visible) {
83 mode = grp->is_bin_visible(kobj, *bin_attr, i);
84 if (!mode)
85 continue;
86 }
87
88 WARN(mode & ~(SYSFS_PREALLOC | 0664),
89 "Attribute %s: Invalid permissions 0%o\n",
90 (*bin_attr)->attr.name, mode);
91
92 mode &= SYSFS_PREALLOC | 0664;
80 error = sysfs_add_file_mode_ns(parent, 93 error = sysfs_add_file_mode_ns(parent,
81 &(*bin_attr)->attr, true, 94 &(*bin_attr)->attr, true,
82 (*bin_attr)->attr.mode, NULL); 95 mode, NULL);
83 if (error) 96 if (error)
84 break; 97 break;
85 } 98 }
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 9f65758311a4..2f66050d073b 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -64,10 +64,18 @@ do { \
64 * a new subdirectory with this name. 64 * a new subdirectory with this name.
65 * @is_visible: Optional: Function to return permissions associated with an 65 * @is_visible: Optional: Function to return permissions associated with an
66 * attribute of the group. Will be called repeatedly for each 66 * attribute of the group. Will be called repeatedly for each
67 * attribute in the group. Only read/write permissions as well as 67 * non-binary attribute in the group. Only read/write
68 * SYSFS_PREALLOC are accepted. Must return 0 if an attribute is 68 * permissions as well as SYSFS_PREALLOC are accepted. Must
69 * not visible. The returned value will replace static permissions 69 * return 0 if an attribute is not visible. The returned value
70 * defined in struct attribute or struct bin_attribute. 70 * will replace static permissions defined in struct attribute.
71 * @is_bin_visible:
72 * Optional: Function to return permissions associated with a
73 * binary attribute of the group. Will be called repeatedly
74 * for each binary attribute in the group. Only read/write
75 * permissions as well as SYSFS_PREALLOC are accepted. Must
76 * return 0 if a binary attribute is not visible. The returned
77 * value will replace static permissions defined in
78 * struct bin_attribute.
71 * @attrs: Pointer to NULL terminated list of attributes. 79 * @attrs: Pointer to NULL terminated list of attributes.
72 * @bin_attrs: Pointer to NULL terminated list of binary attributes. 80 * @bin_attrs: Pointer to NULL terminated list of binary attributes.
73 * Either attrs or bin_attrs or both must be provided. 81 * Either attrs or bin_attrs or both must be provided.
@@ -76,6 +84,8 @@ struct attribute_group {
76 const char *name; 84 const char *name;
77 umode_t (*is_visible)(struct kobject *, 85 umode_t (*is_visible)(struct kobject *,
78 struct attribute *, int); 86 struct attribute *, int);
87 umode_t (*is_bin_visible)(struct kobject *,
88 struct bin_attribute *, int);
79 struct attribute **attrs; 89 struct attribute **attrs;
80 struct bin_attribute **bin_attrs; 90 struct bin_attribute **bin_attrs;
81}; 91};