mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-23 20:24:12 +08:00
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 <lukas@wunner.de> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Ard Biesheuvel <ardb@kernel.org> Link: https://lore.kernel.org/r/5ed62b197a442ec6db53d8746d9d806dd0576e2d.1712410202.git.lukas@wunner.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
85d2b0aa17
commit
d48c03198a
@ -783,3 +783,30 @@ int sysfs_emit_at(char *buf, int at, const char *fmt, ...)
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(sysfs_emit_at);
|
EXPORT_SYMBOL_GPL(sysfs_emit_at);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sysfs_bin_attr_simple_read - read callback to simply copy from memory.
|
||||||
|
* @file: attribute file which is being read.
|
||||||
|
* @kobj: object to which the attribute belongs.
|
||||||
|
* @attr: attribute descriptor.
|
||||||
|
* @buf: destination buffer.
|
||||||
|
* @off: offset in bytes from which to read.
|
||||||
|
* @count: maximum number of bytes to read.
|
||||||
|
*
|
||||||
|
* Simple ->read() callback for bin_attributes backed by a buffer in memory.
|
||||||
|
* The @private and @size members in struct bin_attribute must be set to the
|
||||||
|
* buffer's location and size before the bin_attribute is created in sysfs.
|
||||||
|
*
|
||||||
|
* Bounds check for @off and @count is done in sysfs_kf_bin_read().
|
||||||
|
* Negative value check for @off is done in vfs_setpos() and default_llseek().
|
||||||
|
*
|
||||||
|
* Returns number of bytes written to @buf.
|
||||||
|
*/
|
||||||
|
ssize_t sysfs_bin_attr_simple_read(struct file *file, struct kobject *kobj,
|
||||||
|
struct bin_attribute *attr, char *buf,
|
||||||
|
loff_t off, size_t count)
|
||||||
|
{
|
||||||
|
memcpy(buf, attr->private + off, count);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(sysfs_bin_attr_simple_read);
|
||||||
|
@ -371,6 +371,17 @@ struct bin_attribute bin_attr_##_name = __BIN_ATTR_ADMIN_RO(_name, _size)
|
|||||||
#define BIN_ATTR_ADMIN_RW(_name, _size) \
|
#define BIN_ATTR_ADMIN_RW(_name, _size) \
|
||||||
struct bin_attribute bin_attr_##_name = __BIN_ATTR_ADMIN_RW(_name, _size)
|
struct bin_attribute bin_attr_##_name = __BIN_ATTR_ADMIN_RW(_name, _size)
|
||||||
|
|
||||||
|
#define __BIN_ATTR_SIMPLE_RO(_name, _mode) { \
|
||||||
|
.attr = { .name = __stringify(_name), .mode = _mode }, \
|
||||||
|
.read = sysfs_bin_attr_simple_read, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BIN_ATTR_SIMPLE_RO(_name) \
|
||||||
|
struct bin_attribute bin_attr_##_name = __BIN_ATTR_SIMPLE_RO(_name, 0444)
|
||||||
|
|
||||||
|
#define BIN_ATTR_SIMPLE_ADMIN_RO(_name) \
|
||||||
|
struct bin_attribute bin_attr_##_name = __BIN_ATTR_SIMPLE_RO(_name, 0400)
|
||||||
|
|
||||||
struct sysfs_ops {
|
struct sysfs_ops {
|
||||||
ssize_t (*show)(struct kobject *, struct attribute *, char *);
|
ssize_t (*show)(struct kobject *, struct attribute *, char *);
|
||||||
ssize_t (*store)(struct kobject *, struct attribute *, const char *, size_t);
|
ssize_t (*store)(struct kobject *, struct attribute *, const char *, size_t);
|
||||||
@ -478,6 +489,10 @@ int sysfs_emit(char *buf, const char *fmt, ...);
|
|||||||
__printf(3, 4)
|
__printf(3, 4)
|
||||||
int sysfs_emit_at(char *buf, int at, const char *fmt, ...);
|
int sysfs_emit_at(char *buf, int at, const char *fmt, ...);
|
||||||
|
|
||||||
|
ssize_t sysfs_bin_attr_simple_read(struct file *file, struct kobject *kobj,
|
||||||
|
struct bin_attribute *attr, char *buf,
|
||||||
|
loff_t off, size_t count);
|
||||||
|
|
||||||
#else /* CONFIG_SYSFS */
|
#else /* CONFIG_SYSFS */
|
||||||
|
|
||||||
static inline int sysfs_create_dir_ns(struct kobject *kobj, const void *ns)
|
static inline int sysfs_create_dir_ns(struct kobject *kobj, const void *ns)
|
||||||
|
Loading…
Reference in New Issue
Block a user