From e7eb1f60e4ae943c79edc6afc1baf486c3bd14b6 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 30 Jan 2024 10:46:27 -0800 Subject: [PATCH 1/7] sysfs: Introduce a mechanism to hide static attribute_groups Add a mechanism for named attribute_groups to hide their directory at sysfs_update_group() time, or otherwise skip emitting the group directory when the group is first registered. It piggybacks on is_visible() in a similar manner as SYSFS_PREALLOC, i.e. special flags in the upper bits of the returned mode. To use it, specify a symbol prefix to DEFINE_SYSFS_GROUP_VISIBLE(), and then pass that same prefix to SYSFS_GROUP_VISIBLE() when assigning the @is_visible() callback: DEFINE_SYSFS_GROUP_VISIBLE($prefix) struct attribute_group $prefix_group = { .name = $name, .is_visible = SYSFS_GROUP_VISIBLE($prefix), }; SYSFS_GROUP_VISIBLE() expects a definition of $prefix_group_visible() and $prefix_attr_visible(), where $prefix_group_visible() just returns true / false and $prefix_attr_visible() behaves as normal. The motivation for this capability is to centralize PCI device authentication in the PCI core with a named sysfs group while keeping that group hidden for devices and platforms that do not meet the requirements. In a PCI topology, most devices will not support authentication, a small subset will support just PCI CMA (Component Measurement and Authentication), a smaller subset will support PCI CMA + PCIe IDE (Link Integrity and Encryption), and only next generation server hosts will start to include a platform TSM (TEE Security Manager). Without this capability the alternatives are: * Check if all attributes are invisible and if so, hide the directory. Beyond trouble getting this to work [1], this is an ABI change for scenarios if userspace happens to depend on group visibility absent any attributes. I.e. this new capability avoids regression since it does not retroactively apply to existing cases. * Publish an empty /sys/bus/pci/devices/$pdev/tsm/ directory for all PCI devices (i.e. for the case when TSM platform support is present, but device support is absent). Unfortunate that this will be a vestigial empty directory in the vast majority of cases. * Reintroduce usage of runtime calls to sysfs_{create,remove}_group() in the PCI core. Bjorn has already indicated that he does not want to see any growth of pci_sysfs_init() [2]. * Drop the named group and simulate a directory by prefixing all TSM-related attributes with "tsm_". Unfortunate to not use the naming capability of a sysfs group as intended. In comparison, there is a small potential for regression if for some reason an @is_visible() callback had dependencies on how many times it was called. Additionally, it is no longer an error to update a group that does not have its directory already present, and it is no longer a WARN() to remove a group that was never visible. Link: https://lore.kernel.org/all/2024012321-envious-procedure-4a58@gregkh/ [1] Link: https://lore.kernel.org/linux-pci/20231019200110.GA1410324@bhelgaas/ [2] Signed-off-by: Dan Williams Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/group.c | 45 ++++++++++++++++++++++++------- include/linux/sysfs.h | 63 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 87 insertions(+), 21 deletions(-) diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c index 138676463336c7..ccb275cdabcb6f 100644 --- a/fs/sysfs/group.c +++ b/fs/sysfs/group.c @@ -31,6 +31,17 @@ static void remove_files(struct kernfs_node *parent, kernfs_remove_by_name(parent, (*bin_attr)->attr.name); } +static umode_t __first_visible(const struct attribute_group *grp, struct kobject *kobj) +{ + if (grp->attrs && grp->is_visible) + return grp->is_visible(kobj, grp->attrs[0], 0); + + if (grp->bin_attrs && grp->is_bin_visible) + return grp->is_bin_visible(kobj, grp->bin_attrs[0], 0); + + return 0; +} + static int create_files(struct kernfs_node *parent, struct kobject *kobj, kuid_t uid, kgid_t gid, const struct attribute_group *grp, int update) @@ -52,6 +63,7 @@ static int create_files(struct kernfs_node *parent, struct kobject *kobj, kernfs_remove_by_name(parent, (*attr)->name); if (grp->is_visible) { mode = grp->is_visible(kobj, *attr, i); + mode &= ~SYSFS_GROUP_INVISIBLE; if (!mode) continue; } @@ -81,6 +93,7 @@ static int create_files(struct kernfs_node *parent, struct kobject *kobj, (*bin_attr)->attr.name); if (grp->is_bin_visible) { mode = grp->is_bin_visible(kobj, *bin_attr, i); + mode &= ~SYSFS_GROUP_INVISIBLE; if (!mode) continue; } @@ -127,16 +140,31 @@ static int internal_create_group(struct kobject *kobj, int update, kobject_get_ownership(kobj, &uid, &gid); if (grp->name) { + umode_t mode = __first_visible(grp, kobj); + + if (mode & SYSFS_GROUP_INVISIBLE) + mode = 0; + else + mode = S_IRWXU | S_IRUGO | S_IXUGO; + if (update) { kn = kernfs_find_and_get(kobj->sd, grp->name); if (!kn) { - pr_warn("Can't update unknown attr grp name: %s/%s\n", - kobj->name, grp->name); - return -EINVAL; + pr_debug("attr grp %s/%s not created yet\n", + kobj->name, grp->name); + /* may have been invisible prior to this update */ + update = 0; + } else if (!mode) { + sysfs_remove_group(kobj, grp); + kernfs_put(kn); + return 0; } - } else { - kn = kernfs_create_dir_ns(kobj->sd, grp->name, - S_IRWXU | S_IRUGO | S_IXUGO, + } + + if (!update) { + if (!mode) + return 0; + kn = kernfs_create_dir_ns(kobj->sd, grp->name, mode, uid, gid, kobj, NULL); if (IS_ERR(kn)) { if (PTR_ERR(kn) == -EEXIST) @@ -279,9 +307,8 @@ void sysfs_remove_group(struct kobject *kobj, if (grp->name) { kn = kernfs_find_and_get(parent, grp->name); if (!kn) { - WARN(!kn, KERN_WARNING - "sysfs group '%s' not found for kobject '%s'\n", - grp->name, kobject_name(kobj)); + pr_debug("sysfs group '%s' not found for kobject '%s'\n", + grp->name, kobject_name(kobj)); return; } } else { diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index b717a70219f651..a42642b277dd07 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -61,22 +61,32 @@ do { \ /** * struct attribute_group - data structure used to declare an attribute group. * @name: Optional: Attribute group name - * If specified, the attribute group will be created in - * a new subdirectory with this name. + * If specified, the attribute group will be created in a + * new subdirectory with this name. Additionally when a + * group is named, @is_visible and @is_bin_visible may + * return SYSFS_GROUP_INVISIBLE to control visibility of + * the directory itself. * @is_visible: Optional: Function to return permissions associated with an - * attribute of the group. Will be called repeatedly for each - * non-binary attribute in the group. Only read/write + * attribute of the group. Will be called repeatedly for + * each non-binary attribute in the group. Only read/write * permissions as well as SYSFS_PREALLOC are accepted. Must - * return 0 if an attribute is not visible. The returned value - * will replace static permissions defined in struct attribute. + * return 0 if an attribute is not visible. The returned + * value will replace static permissions defined in struct + * attribute. Use SYSFS_GROUP_VISIBLE() when assigning this + * callback to specify separate _group_visible() and + * _attr_visible() handlers. * @is_bin_visible: * Optional: Function to return permissions associated with a * binary attribute of the group. Will be called repeatedly * for each binary attribute in the group. Only read/write - * permissions as well as SYSFS_PREALLOC are accepted. Must - * return 0 if a binary attribute is not visible. The returned - * value will replace static permissions defined in - * struct bin_attribute. + * permissions as well as SYSFS_PREALLOC (and the + * visibility flags for named groups) are accepted. Must + * return 0 if a binary attribute is not visible. The + * returned value will replace static permissions defined + * in struct bin_attribute. If @is_visible is not set, Use + * SYSFS_GROUP_VISIBLE() when assigning this callback to + * specify separate _group_visible() and _attr_visible() + * handlers. * @attrs: Pointer to NULL terminated list of attributes. * @bin_attrs: Pointer to NULL terminated list of binary attributes. * Either attrs or bin_attrs or both must be provided. @@ -91,13 +101,42 @@ struct attribute_group { struct bin_attribute **bin_attrs; }; +#define SYSFS_PREALLOC 010000 +#define SYSFS_GROUP_INVISIBLE 020000 + +/* + * The first call to is_visible() in the create / update path may + * indicate visibility for the entire group + */ +#define DEFINE_SYSFS_GROUP_VISIBLE(name) \ + static inline umode_t sysfs_group_visible_##name( \ + struct kobject *kobj, struct attribute *attr, int n) \ + { \ + if (n == 0 && !name##_group_visible(kobj)) \ + return SYSFS_GROUP_INVISIBLE; \ + return name##_attr_visible(kobj, attr, n); \ + } + +/* + * Same as DEFINE_SYSFS_GROUP_VISIBLE, but for groups with only binary + * attributes + */ +#define DEFINE_SYSFS_BIN_GROUP_VISIBLE(name) \ + static inline umode_t sysfs_group_visible_##name( \ + struct kobject *kobj, struct bin_attribute *attr, int n) \ + { \ + if (n == 0 && !name##_group_visible(kobj)) \ + return SYSFS_GROUP_INVISIBLE; \ + return name##_attr_visible(kobj, attr, n); \ + } + +#define SYSFS_GROUP_VISIBLE(fn) sysfs_group_visible_##fn + /* * Use these macros to make defining attributes easier. * See include/linux/device.h for examples.. */ -#define SYSFS_PREALLOC 010000 - #define __ATTR(_name, _mode, _show, _store) { \ .attr = {.name = __stringify(_name), \ .mode = VERIFY_OCTAL_PERMISSIONS(_mode) }, \ From 07cc3d63e4732ea3c6ef79f23f78be082b9198ea Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 30 Jan 2024 10:46:28 -0800 Subject: [PATCH 2/7] soundwire: sysfs: move sdw_slave_dev_attr_group into the existing list of groups The sysfs logic already creates a list of groups for the device, so add the sdw_slave_dev_attr_group group to that list instead of having to do a two-step process of adding a group list and then an individual group. This is a step on the way to moving all of the sysfs attribute handling into the default driver core attribute group logic so that the soundwire core does not have to do any of it manually. Cc: Vinod Koul Cc: Bard Liao Cc: Pierre-Louis Bossart Cc: Sanyog Kale Cc: alsa-devel@alsa-project.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/soundwire/sysfs_slave.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/soundwire/sysfs_slave.c b/drivers/soundwire/sysfs_slave.c index 3210359cd94428..83e3f6cc325008 100644 --- a/drivers/soundwire/sysfs_slave.c +++ b/drivers/soundwire/sysfs_slave.c @@ -105,7 +105,10 @@ static struct attribute *slave_attrs[] = { &dev_attr_modalias.attr, NULL, }; -ATTRIBUTE_GROUPS(slave); + +static const struct attribute_group slave_attr_group = { + .attrs = slave_attrs, +}; static struct attribute *slave_dev_attrs[] = { &dev_attr_mipi_revision.attr, @@ -190,6 +193,12 @@ static const struct attribute_group dp0_group = { .name = "dp0", }; +static const struct attribute_group *slave_groups[] = { + &slave_attr_group, + &sdw_slave_dev_attr_group, + NULL, +}; + int sdw_slave_sysfs_init(struct sdw_slave *slave) { int ret; @@ -198,10 +207,6 @@ int sdw_slave_sysfs_init(struct sdw_slave *slave) if (ret < 0) return ret; - ret = devm_device_add_group(&slave->dev, &sdw_slave_dev_attr_group); - if (ret < 0) - return ret; - if (slave->prop.dp0_prop) { ret = devm_device_add_group(&slave->dev, &dp0_group); if (ret < 0) From 036080b978a14694d65ae30f39d645c9cb53b185 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 30 Jan 2024 10:46:29 -0800 Subject: [PATCH 3/7] soundwire: sysfs: cleanup the logic for creating the dp0 sysfs attributes There's no need to special-case the dp0 sysfs attributes, the is_visible() callback in the attribute group can handle that for us, so add that and add it to the attribute group list making the logic simpler overall. This is a step on the way to moving all of the sysfs attribute handling into the default driver core attribute group logic so that the soundwire core does not have to do any of it manually. Cc: Vinod Koul Cc: Bard Liao Cc: Pierre-Louis Bossart Cc: Sanyog Kale Cc: alsa-devel@alsa-project.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/soundwire/sysfs_slave.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/drivers/soundwire/sysfs_slave.c b/drivers/soundwire/sysfs_slave.c index 83e3f6cc325008..8876c7807048bb 100644 --- a/drivers/soundwire/sysfs_slave.c +++ b/drivers/soundwire/sysfs_slave.c @@ -184,18 +184,40 @@ static struct attribute *dp0_attrs[] = { NULL, }; +static umode_t dp0_attr_visible(struct kobject *kobj, struct attribute *attr, + int n) +{ + struct sdw_slave *slave = dev_to_sdw_dev(kobj_to_dev(kobj)); + + if (slave->prop.dp0_prop) + return attr->mode; + return 0; +} + +static bool dp0_group_visible(struct kobject *kobj) +{ + struct sdw_slave *slave = dev_to_sdw_dev(kobj_to_dev(kobj)); + + if (slave->prop.dp0_prop) + return true; + return false; +} +DEFINE_SYSFS_GROUP_VISIBLE(dp0); + /* * we don't use ATTRIBUTES_GROUP here since we want to add a subdirectory * for dp0-level properties */ static const struct attribute_group dp0_group = { .attrs = dp0_attrs, + .is_visible = SYSFS_GROUP_VISIBLE(dp0), .name = "dp0", }; static const struct attribute_group *slave_groups[] = { &slave_attr_group, &sdw_slave_dev_attr_group, + &dp0_group, NULL, }; @@ -207,12 +229,6 @@ int sdw_slave_sysfs_init(struct sdw_slave *slave) if (ret < 0) return ret; - if (slave->prop.dp0_prop) { - ret = devm_device_add_group(&slave->dev, &dp0_group); - if (ret < 0) - return ret; - } - if (slave->prop.source_ports || slave->prop.sink_ports) { ret = sdw_slave_sysfs_dpn_init(slave); if (ret < 0) From e1e548b100fb47335d9f83f72f3a3b7d377e8a15 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 30 Jan 2024 10:46:30 -0800 Subject: [PATCH 4/7] soundwire: sysfs: have the driver core handle the creation of the device groups The driver core supports the ability to handle the creation and removal of device-specific sysfs files in a race-free manner. Take advantage of that by converting this driver to use this by moving the sysfs attributes into a group and assigning the dev_groups pointer to it. Cc: Vinod Koul Cc: Bard Liao Cc: Pierre-Louis Bossart Cc: Sanyog Kale Cc: alsa-devel@alsa-project.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/soundwire/bus_type.c | 1 + drivers/soundwire/sysfs_local.h | 3 +++ drivers/soundwire/sysfs_slave.c | 6 +----- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c index 9fa93bb923d70f..5abe5593395a26 100644 --- a/drivers/soundwire/bus_type.c +++ b/drivers/soundwire/bus_type.c @@ -221,6 +221,7 @@ int __sdw_register_driver(struct sdw_driver *drv, struct module *owner) drv->driver.probe = sdw_drv_probe; drv->driver.remove = sdw_drv_remove; drv->driver.shutdown = sdw_drv_shutdown; + drv->driver.dev_groups = sdw_attr_groups; return driver_register(&drv->driver); } diff --git a/drivers/soundwire/sysfs_local.h b/drivers/soundwire/sysfs_local.h index 7268bc24c5384f..3ab8658a77823f 100644 --- a/drivers/soundwire/sysfs_local.h +++ b/drivers/soundwire/sysfs_local.h @@ -11,6 +11,9 @@ /* basic attributes to report status of Slave (attachment, dev_num) */ extern const struct attribute_group *sdw_slave_status_attr_groups[]; +/* attributes for all soundwire devices */ +extern const struct attribute_group *sdw_attr_groups[]; + /* additional device-managed properties reported after driver probe */ int sdw_slave_sysfs_init(struct sdw_slave *slave); int sdw_slave_sysfs_dpn_init(struct sdw_slave *slave); diff --git a/drivers/soundwire/sysfs_slave.c b/drivers/soundwire/sysfs_slave.c index 8876c7807048bb..3afc0dc06c982c 100644 --- a/drivers/soundwire/sysfs_slave.c +++ b/drivers/soundwire/sysfs_slave.c @@ -214,7 +214,7 @@ static const struct attribute_group dp0_group = { .name = "dp0", }; -static const struct attribute_group *slave_groups[] = { +const struct attribute_group *sdw_attr_groups[] = { &slave_attr_group, &sdw_slave_dev_attr_group, &dp0_group, @@ -225,10 +225,6 @@ int sdw_slave_sysfs_init(struct sdw_slave *slave) { int ret; - ret = devm_device_add_groups(&slave->dev, slave_groups); - if (ret < 0) - return ret; - if (slave->prop.source_ports || slave->prop.sink_ports) { ret = sdw_slave_sysfs_dpn_init(slave); if (ret < 0) From cf82e91835b72c26d867ac4f22c84dffb3f0ac73 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 30 Jan 2024 10:46:31 -0800 Subject: [PATCH 5/7] soundwire: sysfs: remove sdw_slave_sysfs_init() Now that sdw_slave_sysfs_init() only calls sdw_slave_sysfs_dpn_init(), just do that instead and remove sdw_slave_sysfs_init() to get it out of the way to save a bit of logic and code size. Cc: Vinod Koul Cc: Bard Liao Cc: Pierre-Louis Bossart Cc: Sanyog Kale Cc: alsa-devel@alsa-project.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/soundwire/bus_type.c | 4 ++-- drivers/soundwire/sysfs_local.h | 1 - drivers/soundwire/sysfs_slave.c | 13 ------------- drivers/soundwire/sysfs_slave_dpn.c | 3 +++ 4 files changed, 5 insertions(+), 16 deletions(-) diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c index 5abe5593395a26..6085eb8c8d8558 100644 --- a/drivers/soundwire/bus_type.c +++ b/drivers/soundwire/bus_type.c @@ -126,8 +126,8 @@ static int sdw_drv_probe(struct device *dev) if (slave->prop.use_domain_irq) sdw_irq_create_mapping(slave); - /* init the sysfs as we have properties now */ - ret = sdw_slave_sysfs_init(slave); + /* init the dynamic sysfs attributes we need */ + ret = sdw_slave_sysfs_dpn_init(slave); if (ret < 0) dev_warn(dev, "Slave sysfs init failed:%d\n", ret); diff --git a/drivers/soundwire/sysfs_local.h b/drivers/soundwire/sysfs_local.h index 3ab8658a77823f..fa048e112629a2 100644 --- a/drivers/soundwire/sysfs_local.h +++ b/drivers/soundwire/sysfs_local.h @@ -15,7 +15,6 @@ extern const struct attribute_group *sdw_slave_status_attr_groups[]; extern const struct attribute_group *sdw_attr_groups[]; /* additional device-managed properties reported after driver probe */ -int sdw_slave_sysfs_init(struct sdw_slave *slave); int sdw_slave_sysfs_dpn_init(struct sdw_slave *slave); #endif /* __SDW_SYSFS_LOCAL_H */ diff --git a/drivers/soundwire/sysfs_slave.c b/drivers/soundwire/sysfs_slave.c index 3afc0dc06c982c..0eefc205f6970c 100644 --- a/drivers/soundwire/sysfs_slave.c +++ b/drivers/soundwire/sysfs_slave.c @@ -221,19 +221,6 @@ const struct attribute_group *sdw_attr_groups[] = { NULL, }; -int sdw_slave_sysfs_init(struct sdw_slave *slave) -{ - int ret; - - if (slave->prop.source_ports || slave->prop.sink_ports) { - ret = sdw_slave_sysfs_dpn_init(slave); - if (ret < 0) - return ret; - } - - return 0; -} - /* * the status is shown in capital letters for UNATTACHED and RESERVED * on purpose, to highligh users to the fact that these status values diff --git a/drivers/soundwire/sysfs_slave_dpn.c b/drivers/soundwire/sysfs_slave_dpn.c index c4b6543c09fd67..a3fb380ee51941 100644 --- a/drivers/soundwire/sysfs_slave_dpn.c +++ b/drivers/soundwire/sysfs_slave_dpn.c @@ -283,6 +283,9 @@ int sdw_slave_sysfs_dpn_init(struct sdw_slave *slave) int ret; int i; + if (!slave->prop.source_ports && !slave->prop.sink_ports) + return 0; + mask = slave->prop.source_ports; for_each_set_bit(i, &mask, 32) { ret = add_all_attributes(&slave->dev, i, 1); From 410f9d1959d581003823ee0b4a010ff8d0e52b93 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 30 Jan 2024 10:46:32 -0800 Subject: [PATCH 6/7] soundwire: sysfs: remove unneeded ATTRIBUTE_GROUPS() comments Now that we manually created our own attribute group list, the outdated ATTRIBUTE_GROUPS() comments can be removed as they are not needed at all. Cc: Vinod Koul Cc: Bard Liao Cc: Pierre-Louis Bossart Cc: Sanyog Kale Cc: alsa-devel@alsa-project.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/soundwire/sysfs_slave.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/soundwire/sysfs_slave.c b/drivers/soundwire/sysfs_slave.c index 0eefc205f6970c..f4259710dd0f72 100644 --- a/drivers/soundwire/sysfs_slave.c +++ b/drivers/soundwire/sysfs_slave.c @@ -129,10 +129,6 @@ static struct attribute *slave_dev_attrs[] = { NULL, }; -/* - * we don't use ATTRIBUTES_GROUP here since we want to add a subdirectory - * for device-level properties - */ static const struct attribute_group sdw_slave_dev_attr_group = { .attrs = slave_dev_attrs, .name = "dev-properties", @@ -204,10 +200,6 @@ static bool dp0_group_visible(struct kobject *kobj) } DEFINE_SYSFS_GROUP_VISIBLE(dp0); -/* - * we don't use ATTRIBUTES_GROUP here since we want to add a subdirectory - * for dp0-level properties - */ static const struct attribute_group dp0_group = { .attrs = dp0_attrs, .is_visible = SYSFS_GROUP_VISIBLE(dp0), From 8960d1a50d923a52e02047d23fd58b42bc56cc1d Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 16 Feb 2024 15:51:16 -0600 Subject: [PATCH 7/7] sysfs: add debug patch suggested by Dan Williams https://lore.kernel.org/all/65baa2c754e8d_37ad2941f@dwillia2-xfh.jf.intel.com.notmuch/ Signed-off-by: Pierre-Louis Bossart --- fs/sysfs/group.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c index ccb275cdabcb6f..683c0b10990b79 100644 --- a/fs/sysfs/group.c +++ b/fs/sysfs/group.c @@ -33,11 +33,17 @@ static void remove_files(struct kernfs_node *parent, static umode_t __first_visible(const struct attribute_group *grp, struct kobject *kobj) { - if (grp->attrs && grp->is_visible) + if (grp->attrs && grp->is_visible) { + pr_info("kobj: %s is_visible: %pS\n", kobj->name, + grp->is_visible); return grp->is_visible(kobj, grp->attrs[0], 0); + } - if (grp->bin_attrs && grp->is_bin_visible) + if (grp->bin_attrs && grp->is_bin_visible) { + pr_info("kobj: %s is_bin_visible: %pS\n", kobj->name, + grp->is_bin_visible); return grp->is_bin_visible(kobj, grp->bin_attrs[0], 0); + } return 0; } @@ -62,6 +68,8 @@ static int create_files(struct kernfs_node *parent, struct kobject *kobj, if (update) kernfs_remove_by_name(parent, (*attr)->name); if (grp->is_visible) { + pr_info("kobj: %s is_visible: %pS\n", + kobj->name, grp->is_visible); mode = grp->is_visible(kobj, *attr, i); mode &= ~SYSFS_GROUP_INVISIBLE; if (!mode) @@ -92,6 +100,8 @@ static int create_files(struct kernfs_node *parent, struct kobject *kobj, kernfs_remove_by_name(parent, (*bin_attr)->attr.name); if (grp->is_bin_visible) { + pr_info("kobj: %s is_bin_visible: %pS\n", + kobj->name, grp->is_bin_visible); mode = grp->is_bin_visible(kobj, *bin_attr, i); mode &= ~SYSFS_GROUP_INVISIBLE; if (!mode)