On Sun, Nov 03, 2024 at 05:03:31PM +0000, Thomas Weißschuh wrote: > Several drivers need to dynamically calculate the size of an binary > attribute. Currently this is done by assigning attr->size from the > is_bin_visible() callback. s/an binary/a binary/ > This has drawbacks: > * It is not documented. > * A single attribute can be instantiated multiple times, overwriting the > shared size field. > * It prevents the structure to be moved to read-only memory. > > Introduce a new dedicated callback to calculate the size of the > attribute. > > Signed-off-by: Thomas Weißschuh <linux@xxxxxxxxxxxxxx> > --- > fs/sysfs/group.c | 2 ++ > include/linux/sysfs.h | 8 ++++++++ > 2 files changed, 10 insertions(+) > > diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c > index 45b2e92941da1f49dcc71af3781317c61480c956..8b01a7eda5fb3239e138372417d01967c7a3f122 100644 > --- a/fs/sysfs/group.c > +++ b/fs/sysfs/group.c > @@ -98,6 +98,8 @@ static int create_files(struct kernfs_node *parent, struct kobject *kobj, > if (!mode) > continue; > } > + if (grp->bin_size) > + size = grp->bin_size(kobj, *bin_attr, i); > > WARN(mode & ~(SYSFS_PREALLOC | 0664), > "Attribute %s: Invalid permissions 0%o\n", > diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h > index c4e64dc112063f7cb89bf66059d0338716089e87..4746cccb95898b24df6f53de9421ea7649b5568f 100644 > --- a/include/linux/sysfs.h > +++ b/include/linux/sysfs.h > @@ -87,6 +87,11 @@ do { \ > * SYSFS_GROUP_VISIBLE() when assigning this callback to > * specify separate _group_visible() and _attr_visible() > * handlers. > + * @bin_size: > + * Optional: Function to return the size of a binary attribute > + * of the group. Will be called repeatedly for each binary > + * attribute in the group. Overwrites the size field embedded > + * inside the attribute itself. "Overwrites" suggests that we write over the size field in the single shared attribute. But that's not what create_files() does. create_files() instantiates sysfs files from the attribute template. Previously each instance used the size from the shared attribute. With this patch, if ->bin_size() exists, its return value is the size of this particular instance, over*riding* the default size from the shared attribute. This description follows the language of other function pointers, which was the right approach. But I think the existing language would be more helpful if it called out the difference between the attribute itself (a potentially read-only singleton structure shared by all kobjects with this attribute) and the instantiation of that attribute for each kobject. For example, @bin_size: Optional: Function to return the size of this kobject's instantiation of a binary attribute. If present, it is called for each bin_attribute in the group and overrides the default size from the bin_attribute template. This is nice work, thanks for doing it! > * @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. > @@ -97,6 +102,9 @@ struct attribute_group { > struct attribute *, int); > umode_t (*is_bin_visible)(struct kobject *, > struct bin_attribute *, int); > + size_t (*bin_size)(struct kobject *, > + const struct bin_attribute *, > + int); > struct attribute **attrs; > struct bin_attribute **bin_attrs; > }; > > -- > 2.47.0 >