Skip to content

Commit eb2e6c3

Browse files
t-8chgregkh
authored andcommitted
sysfs: bin_attribute: add const read/write callback variants
To make it possible to put struct bin_attribute into read-only memory, the sysfs core has to stop passing mutable pointers to the read() and write() callbacks. As there are numerous implementors of these callbacks throughout the tree it's not possible to change all of them at once. To enable a step-by-step transition, add new variants of the read() and write() callbacks which differ only in the constness of the struct bin_attribute argument. As most binary attributes are defined through macros, extend these macros to transparently handle both variants of callbacks to minimize the churn during the transition. As soon as all handlers are switch to the const variant, the non-const one can be removed together with the transition machinery. Signed-off-by: Thomas Weißschuh <[email protected]> Acked-by: Krzysztof Wilczyński <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent ae587a5 commit eb2e6c3

File tree

2 files changed

+40
-7
lines changed

2 files changed

+40
-7
lines changed

fs/sysfs/file.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,12 @@ static ssize_t sysfs_kf_bin_read(struct kernfs_open_file *of, char *buf,
9191
count = size - pos;
9292
}
9393

94-
if (!battr->read)
94+
if (!battr->read && !battr->read_new)
9595
return -EIO;
9696

97+
if (battr->read_new)
98+
return battr->read_new(of->file, kobj, battr, buf, pos, count);
99+
97100
return battr->read(of->file, kobj, battr, buf, pos, count);
98101
}
99102

@@ -152,9 +155,12 @@ static ssize_t sysfs_kf_bin_write(struct kernfs_open_file *of, char *buf,
152155
if (!count)
153156
return 0;
154157

155-
if (!battr->write)
158+
if (!battr->write && !battr->write_new)
156159
return -EIO;
157160

161+
if (battr->write_new)
162+
return battr->write_new(of->file, kobj, battr, buf, pos, count);
163+
158164
return battr->write(of->file, kobj, battr, buf, pos, count);
159165
}
160166

@@ -323,13 +329,19 @@ int sysfs_add_bin_file_mode_ns(struct kernfs_node *parent,
323329
const struct kernfs_ops *ops;
324330
struct kernfs_node *kn;
325331

332+
if (battr->read && battr->read_new)
333+
return -EINVAL;
334+
335+
if (battr->write && battr->write_new)
336+
return -EINVAL;
337+
326338
if (battr->mmap)
327339
ops = &sysfs_bin_kfops_mmap;
328-
else if (battr->read && battr->write)
340+
else if ((battr->read || battr->read_new) && (battr->write || battr->write_new))
329341
ops = &sysfs_bin_kfops_rw;
330-
else if (battr->read)
342+
else if (battr->read || battr->read_new)
331343
ops = &sysfs_bin_kfops_ro;
332-
else if (battr->write)
344+
else if (battr->write || battr->write_new)
333345
ops = &sysfs_bin_kfops_wo;
334346
else
335347
ops = &sysfs_file_kfops_empty;

include/linux/sysfs.h

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,8 +305,12 @@ struct bin_attribute {
305305
struct address_space *(*f_mapping)(void);
306306
ssize_t (*read)(struct file *, struct kobject *, struct bin_attribute *,
307307
char *, loff_t, size_t);
308+
ssize_t (*read_new)(struct file *, struct kobject *, const struct bin_attribute *,
309+
char *, loff_t, size_t);
308310
ssize_t (*write)(struct file *, struct kobject *, struct bin_attribute *,
309311
char *, loff_t, size_t);
312+
ssize_t (*write_new)(struct file *, struct kobject *,
313+
const struct bin_attribute *, char *, loff_t, size_t);
310314
loff_t (*llseek)(struct file *, struct kobject *, const struct bin_attribute *,
311315
loff_t, int);
312316
int (*mmap)(struct file *, struct kobject *, const struct bin_attribute *attr,
@@ -325,11 +329,28 @@ struct bin_attribute {
325329
*/
326330
#define sysfs_bin_attr_init(bin_attr) sysfs_attr_init(&(bin_attr)->attr)
327331

332+
typedef ssize_t __sysfs_bin_rw_handler_new(struct file *, struct kobject *,
333+
const struct bin_attribute *, char *, loff_t, size_t);
334+
328335
/* macros to create static binary attributes easier */
329336
#define __BIN_ATTR(_name, _mode, _read, _write, _size) { \
330337
.attr = { .name = __stringify(_name), .mode = _mode }, \
331-
.read = _read, \
332-
.write = _write, \
338+
.read = _Generic(_read, \
339+
__sysfs_bin_rw_handler_new * : NULL, \
340+
default : _read \
341+
), \
342+
.read_new = _Generic(_read, \
343+
__sysfs_bin_rw_handler_new * : _read, \
344+
default : NULL \
345+
), \
346+
.write = _Generic(_write, \
347+
__sysfs_bin_rw_handler_new * : NULL, \
348+
default : _write \
349+
), \
350+
.write_new = _Generic(_write, \
351+
__sysfs_bin_rw_handler_new * : _write, \
352+
default : NULL \
353+
), \
333354
.size = _size, \
334355
}
335356

0 commit comments

Comments
 (0)