Skip to content

Commit d48c031

Browse files
l1kgregkh
authored andcommitted
sysfs: Add sysfs_bin_attr_simple_read() helper
When drivers expose a bin_attribute in sysfs which is backed by a buffer in memory, a common pattern is to set the @Private and @SiZe members in struct bin_attribute to the buffer's location and size. The ->read() callback then merely consists of a single memcpy() call. It's not even necessary to perform bounds checks as these are already handled by sysfs_kf_bin_read(). However each driver is so far providing its own ->read() implementation. The pattern is sufficiently frequent to merit a public helper, so add sysfs_bin_attr_simple_read() as well as BIN_ATTR_SIMPLE_RO() and BIN_ATTR_SIMPLE_ADMIN_RO() macros to ease declaration of such bin_attributes and reduce LoC and .text section size. Signed-off-by: Lukas Wunner <[email protected]> Reviewed-by: Greg Kroah-Hartman <[email protected]> Acked-by: Rafael J. Wysocki <[email protected]> Acked-by: Ard Biesheuvel <[email protected]> Link: https://lore.kernel.org/r/5ed62b197a442ec6db53d8746d9d806dd0576e2d.1712410202.git.lukas@wunner.de Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 85d2b0a commit d48c031

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

fs/sysfs/file.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,3 +783,30 @@ int sysfs_emit_at(char *buf, int at, const char *fmt, ...)
783783
return len;
784784
}
785785
EXPORT_SYMBOL_GPL(sysfs_emit_at);
786+
787+
/**
788+
* sysfs_bin_attr_simple_read - read callback to simply copy from memory.
789+
* @file: attribute file which is being read.
790+
* @kobj: object to which the attribute belongs.
791+
* @attr: attribute descriptor.
792+
* @buf: destination buffer.
793+
* @off: offset in bytes from which to read.
794+
* @count: maximum number of bytes to read.
795+
*
796+
* Simple ->read() callback for bin_attributes backed by a buffer in memory.
797+
* The @private and @size members in struct bin_attribute must be set to the
798+
* buffer's location and size before the bin_attribute is created in sysfs.
799+
*
800+
* Bounds check for @off and @count is done in sysfs_kf_bin_read().
801+
* Negative value check for @off is done in vfs_setpos() and default_llseek().
802+
*
803+
* Returns number of bytes written to @buf.
804+
*/
805+
ssize_t sysfs_bin_attr_simple_read(struct file *file, struct kobject *kobj,
806+
struct bin_attribute *attr, char *buf,
807+
loff_t off, size_t count)
808+
{
809+
memcpy(buf, attr->private + off, count);
810+
return count;
811+
}
812+
EXPORT_SYMBOL_GPL(sysfs_bin_attr_simple_read);

include/linux/sysfs.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,17 @@ struct bin_attribute bin_attr_##_name = __BIN_ATTR_ADMIN_RO(_name, _size)
371371
#define BIN_ATTR_ADMIN_RW(_name, _size) \
372372
struct bin_attribute bin_attr_##_name = __BIN_ATTR_ADMIN_RW(_name, _size)
373373

374+
#define __BIN_ATTR_SIMPLE_RO(_name, _mode) { \
375+
.attr = { .name = __stringify(_name), .mode = _mode }, \
376+
.read = sysfs_bin_attr_simple_read, \
377+
}
378+
379+
#define BIN_ATTR_SIMPLE_RO(_name) \
380+
struct bin_attribute bin_attr_##_name = __BIN_ATTR_SIMPLE_RO(_name, 0444)
381+
382+
#define BIN_ATTR_SIMPLE_ADMIN_RO(_name) \
383+
struct bin_attribute bin_attr_##_name = __BIN_ATTR_SIMPLE_RO(_name, 0400)
384+
374385
struct sysfs_ops {
375386
ssize_t (*show)(struct kobject *, struct attribute *, char *);
376387
ssize_t (*store)(struct kobject *, struct attribute *, const char *, size_t);
@@ -478,6 +489,10 @@ int sysfs_emit(char *buf, const char *fmt, ...);
478489
__printf(3, 4)
479490
int sysfs_emit_at(char *buf, int at, const char *fmt, ...);
480491

492+
ssize_t sysfs_bin_attr_simple_read(struct file *file, struct kobject *kobj,
493+
struct bin_attribute *attr, char *buf,
494+
loff_t off, size_t count);
495+
481496
#else /* CONFIG_SYSFS */
482497

483498
static inline int sysfs_create_dir_ns(struct kobject *kobj, const void *ns)

0 commit comments

Comments
 (0)