public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg KH <gregkh@suse.de>
To: linux-kernel@vger.kernel.org
Cc: arnd@arndb.de
Subject: [PATCH] libfs: add simple attribute files
Date: Mon, 20 Jun 2005 15:59:27 -0700	[thread overview]
Message-ID: <1119308367186@kroah.com> (raw)
In-Reply-To: <1119308367477@kroah.com>

[PATCH] libfs: add simple attribute files

Based on the discussion about spufs attributes, this is my suggestion
for a more generic attribute file support that can be used by both
debugfs and spufs.

Simple attribute files behave similarly to sequential files from
a kernel programmers perspective in that a standard set of file
operations is provided and only an open operation needs to
be written that registers file specific get() and set() functions.

These operations are defined as

void foo_set(void *data, u64 val); and
u64 foo_get(void *data);

where data is the inode->u.generic_ip pointer of the file and the
operations just need to make send of that pointer. The infrastructure
makes sure this works correctly with concurrent access and partial
read calls.

A macro named DEFINE_SIMPLE_ATTRIBUTE is provided to further simplify
using the attributes.

This patch already contains the changes for debugfs to use attributes
for its internal file operations.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
commit acaefc25d21f850e47ecc5098d1e0bc442c526be
tree fbc7aa605c71667507b54d3b3320f9a999458dd4
parent 4109aca06cb7b042ea791d0f9d3c9615bc3bf5cd
author Arnd Bergmann <arnd@arndb.de> Wed, 18 May 2005 14:40:59 +0200
committer Greg Kroah-Hartman <gregkh@suse.de> Mon, 20 Jun 2005 15:15:30 -0700

 fs/debugfs/file.c  |   67 +++++++++++++++--------------------
 fs/libfs.c         |  100 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/fs.h |   46 ++++++++++++++++++++++++
 3 files changed, 175 insertions(+), 38 deletions(-)

diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -45,44 +45,15 @@ struct file_operations debugfs_file_oper
 	.open =		default_open,
 };
 
-#define simple_type(type, format, temptype, strtolfn)				\
-static ssize_t read_file_##type(struct file *file, char __user *user_buf,	\
-				size_t count, loff_t *ppos)			\
-{										\
-	char buf[32];								\
-	type *val = file->private_data;						\
-										\
-	snprintf(buf, sizeof(buf), format "\n", *val);				\
-	return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));\
-}										\
-static ssize_t write_file_##type(struct file *file, const char __user *user_buf,\
-				 size_t count, loff_t *ppos)			\
-{										\
-	char *endp;								\
-	char buf[32];								\
-	int buf_size;								\
-	type *val = file->private_data;						\
-	temptype tmp;								\
-										\
-	memset(buf, 0x00, sizeof(buf));						\
-	buf_size = min(count, (sizeof(buf)-1));					\
-	if (copy_from_user(buf, user_buf, buf_size))				\
-		return -EFAULT;							\
-										\
-	tmp = strtolfn(buf, &endp, 0);						\
-	if ((endp == buf) || ((type)tmp != tmp))				\
-		return -EINVAL;							\
-	*val = tmp;								\
-	return count;								\
-}										\
-static struct file_operations fops_##type = {					\
-	.read =		read_file_##type,					\
-	.write =	write_file_##type,					\
-	.open =		default_open,						\
-};
-simple_type(u8, "%c", unsigned long, simple_strtoul);
-simple_type(u16, "%hi", unsigned long, simple_strtoul);
-simple_type(u32, "%i", unsigned long, simple_strtoul);
+static void debugfs_u8_set(void *data, u64 val)
+{
+	*(u8 *)data = val;
+}
+static u64 debugfs_u8_get(void *data)
+{
+	return *(u8 *)data;
+}
+DEFINE_SIMPLE_ATTRIBUTE(fops_u8, debugfs_u8_get, debugfs_u8_set, "%llu\n");
 
 /**
  * debugfs_create_u8 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
@@ -116,6 +87,16 @@ struct dentry *debugfs_create_u8(const c
 }
 EXPORT_SYMBOL_GPL(debugfs_create_u8);
 
+static void debugfs_u16_set(void *data, u64 val)
+{
+	*(u16 *)data = val;
+}
+static u64 debugfs_u16_get(void *data)
+{
+	return *(u16 *)data;
+}
+DEFINE_SIMPLE_ATTRIBUTE(fops_u16, debugfs_u16_get, debugfs_u16_set, "%llu\n");
+
 /**
  * debugfs_create_u16 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
  *
@@ -148,6 +129,16 @@ struct dentry *debugfs_create_u16(const 
 }
 EXPORT_SYMBOL_GPL(debugfs_create_u16);
 
+static void debugfs_u32_set(void *data, u64 val)
+{
+	*(u32 *)data = val;
+}
+static u64 debugfs_u32_get(void *data)
+{
+	return *(u32 *)data;
+}
+DEFINE_SIMPLE_ATTRIBUTE(fops_u32, debugfs_u32_get, debugfs_u32_set, "%llu\n");
+
 /**
  * debugfs_create_u32 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
  *
diff --git a/fs/libfs.c b/fs/libfs.c
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -519,6 +519,102 @@ int simple_transaction_release(struct in
 	return 0;
 }
 
+/* Simple attribute files */
+
+struct simple_attr {
+	u64 (*get)(void *);
+	void (*set)(void *, u64);
+	char get_buf[24];	/* enough to store a u64 and "\n\0" */
+	char set_buf[24];
+	void *data;
+	const char *fmt;	/* format for read operation */
+	struct semaphore sem;	/* protects access to these buffers */
+};
+
+/* simple_attr_open is called by an actual attribute open file operation
+ * to set the attribute specific access operations. */
+int simple_attr_open(struct inode *inode, struct file *file,
+		     u64 (*get)(void *), void (*set)(void *, u64),
+		     const char *fmt)
+{
+	struct simple_attr *attr;
+
+	attr = kmalloc(sizeof(*attr), GFP_KERNEL);
+	if (!attr)
+		return -ENOMEM;
+
+	attr->get = get;
+	attr->set = set;
+	attr->data = inode->u.generic_ip;
+	attr->fmt = fmt;
+	init_MUTEX(&attr->sem);
+
+	file->private_data = attr;
+
+	return nonseekable_open(inode, file);
+}
+
+int simple_attr_close(struct inode *inode, struct file *file)
+{
+	kfree(file->private_data);
+	return 0;
+}
+
+/* read from the buffer that is filled with the get function */
+ssize_t simple_attr_read(struct file *file, char __user *buf,
+			 size_t len, loff_t *ppos)
+{
+	struct simple_attr *attr;
+	size_t size;
+	ssize_t ret;
+
+	attr = file->private_data;
+
+	if (!attr->get)
+		return -EACCES;
+
+	down(&attr->sem);
+	if (*ppos) /* continued read */
+		size = strlen(attr->get_buf);
+	else	  /* first read */
+		size = scnprintf(attr->get_buf, sizeof(attr->get_buf),
+				 attr->fmt,
+				 (unsigned long long)attr->get(attr->data));
+
+	ret = simple_read_from_buffer(buf, len, ppos, attr->get_buf, size);
+	up(&attr->sem);
+	return ret;
+}
+
+/* interpret the buffer as a number to call the set function with */
+ssize_t simple_attr_write(struct file *file, const char __user *buf,
+			  size_t len, loff_t *ppos)
+{
+	struct simple_attr *attr;
+	u64 val;
+	size_t size;
+	ssize_t ret;
+
+	attr = file->private_data;
+
+	if (!attr->set)
+		return -EACCES;
+
+	down(&attr->sem);
+	ret = -EFAULT;
+	size = min(sizeof(attr->set_buf) - 1, len);
+	if (copy_from_user(attr->set_buf, buf, size))
+		goto out;
+
+	ret = len; /* claim we got the whole input */
+	attr->set_buf[size] = '\0';
+	val = simple_strtol(attr->set_buf, NULL, 0);
+	attr->set(attr->data, val);
+out:
+	up(&attr->sem);
+	return ret;
+}
+
 EXPORT_SYMBOL(dcache_dir_close);
 EXPORT_SYMBOL(dcache_dir_lseek);
 EXPORT_SYMBOL(dcache_dir_open);
@@ -547,3 +643,7 @@ EXPORT_SYMBOL(simple_read_from_buffer);
 EXPORT_SYMBOL(simple_transaction_get);
 EXPORT_SYMBOL(simple_transaction_read);
 EXPORT_SYMBOL(simple_transaction_release);
+EXPORT_SYMBOL_GPL(simple_attr_open);
+EXPORT_SYMBOL_GPL(simple_attr_close);
+EXPORT_SYMBOL_GPL(simple_attr_read);
+EXPORT_SYMBOL_GPL(simple_attr_write);
diff --git a/include/linux/fs.h b/include/linux/fs.h
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1657,6 +1657,52 @@ static inline void simple_transaction_se
 	ar->size = n;
 }
 
+/*
+ * simple attribute files
+ *
+ * These attributes behave similar to those in sysfs:
+ *
+ * Writing to an attribute immediately sets a value, an open file can be
+ * written to multiple times.
+ *
+ * Reading from an attribute creates a buffer from the value that might get
+ * read with multiple read calls. When the attribute has been read
+ * completely, no further read calls are possible until the file is opened
+ * again.
+ *
+ * All attributes contain a text representation of a numeric value
+ * that are accessed with the get() and set() functions.
+ */
+#define DEFINE_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt)		\
+static int __fops ## _open(struct inode *inode, struct file *file)	\
+{									\
+	__simple_attr_check_format(__fmt, 0ull);			\
+	return simple_attr_open(inode, file, __get, __set, __fmt);	\
+}									\
+static struct file_operations __fops = {				\
+	.owner	 = THIS_MODULE,						\
+	.open	 = __fops ## _open,					\
+	.release = simple_attr_close,					\
+	.read	 = simple_attr_read,					\
+	.write	 = simple_attr_write,					\
+};
+
+static inline void __attribute__((format(printf, 1, 2)))
+__simple_attr_check_format(const char *fmt, ...)
+{
+	/* don't do anything, just let the compiler check the arguments; */
+}
+
+int simple_attr_open(struct inode *inode, struct file *file,
+		     u64 (*get)(void *), void (*set)(void *, u64),
+		     const char *fmt);
+int simple_attr_close(struct inode *inode, struct file *file);
+ssize_t simple_attr_read(struct file *file, char __user *buf,
+			 size_t len, loff_t *ppos);
+ssize_t simple_attr_write(struct file *file, const char __user *buf,
+			  size_t len, loff_t *ppos);
+
+
 #ifdef CONFIG_SECURITY
 static inline char *alloc_secdata(void)
 {


  reply	other threads:[~2005-06-21  3:56 UTC|newest]

Thread overview: 96+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-06-20 22:55 [GIT PATCH] Driver core changes for 2.6.12 Greg KH
2005-06-20 22:59 ` [PATCH] sysfs_{create|remove}_link should take const char * Greg KH
2005-06-20 22:59   ` [PATCH] kobject_hotplug() should use kobject_name() Greg KH
2005-06-20 22:59     ` [PATCH] Make kobject's name be const char * Greg KH
2005-06-20 22:59       ` [PATCH] kset_hotplug_ops->name shoudl return " Greg KH
2005-06-20 22:59         ` [PATCH] make driver's name be " Greg KH
2005-06-20 22:59           ` [PATCH] Make attributes names " Greg KH
2005-06-20 22:59             ` [PATCH] sysfs: (driver/base) if show/store is missing return -EIO Greg KH
2005-06-20 22:59               ` [PATCH] sysfs: " Greg KH
2005-06-20 22:59                 ` [PATCH] sysfs: (driver/pci) " Greg KH
2005-06-20 22:59                   ` [PATCH] sysfs: (driver/block) " Greg KH
2005-06-20 22:59                     ` [PATCH] sysfs: (rest) " Greg KH
2005-06-20 22:59                       ` [PATCH] INPUT: move to use the new class code, instead of class_simple Greg KH
2005-06-20 22:59                         ` [PATCH] tty: " Greg KH
2005-06-20 22:59                           ` [PATCH] CLASS: move a "simple" class logic into the class core Greg KH
2005-06-20 22:59                             ` [PATCH] class: convert sound/* to use the new class api instead of class_simple Greg KH
2005-06-20 22:59                               ` [PATCH] USB: move the usb hcd code to use the new class code Greg KH
2005-06-20 22:59                                 ` [PATCH] class: convert drivers/block/* to use the new class api instead of class_simple Greg KH
2005-06-20 22:59                                   ` [PATCH] class: convert drivers/ieee1394/* " Greg KH
2005-06-20 22:59                                     ` [PATCH] class: convert drivers/char/* " Greg KH
2005-06-20 22:59                                       ` [PATCH] class: convert drivers/scsi/* " Greg KH
2005-06-20 22:59                                         ` [PATCH] class: convert drivers/* " Greg KH
2005-06-20 22:59                                           ` [PATCH] USB: trivial error path fix Greg KH
2005-06-20 22:59                                             ` [PATCH] class: convert arch/* to use the new class api instead of class_simple Greg KH
2005-06-20 22:59                                               ` [PATCH] class: convert the remaining class_simple users in the kernel to usee the new class api Greg KH
2005-06-20 22:59                                                 ` [PATCH] class: add kerneldoc for the new class functions Greg KH
2005-06-20 22:59                                                   ` [PATCH] class: remove class_simple code, as no one in the tree is using it anymore Greg KH
2005-06-20 22:59                                                     ` [PATCH] fix "make mandocs" after class_simple.c removal Greg KH
2005-06-20 22:59                                                       ` [PATCH] Add a semaphore to struct device to synchronize calls to its driver Greg KH
2005-06-20 22:59                                                         ` [PATCH] fix up ipmi code after class_simple.c removal Greg KH
2005-06-20 22:59                                                           ` [PATCH] Move device/driver code to drivers/base/dd.c Greg KH
2005-06-20 22:59                                                             ` [PATCH] Use driver_for_each_device() instead of manually walking list Greg KH
2005-06-20 22:59                                                               ` [PATCH] Use driver_for_each_device() in drivers/pnp/driver.c " Greg KH
2005-06-20 22:59                                                                 ` [PATCH] Add driver_for_each_device() Greg KH
2005-06-20 22:59                                                                   ` [PATCH] Add a klist to struct bus_type for its drivers Greg KH
2005-06-20 22:59                                                                     ` [PATCH] Add a klist to struct bus_type for its devices Greg KH
2005-06-20 22:59                                                                       ` [PATCH] Add initial implementation of klist helpers Greg KH
2005-06-20 22:59                                                                         ` [PATCH] Add a klist to struct device_driver for the devices bound to it Greg KH
2005-06-20 22:59                                                                           ` [PATCH] Remove the unused device_find() Greg KH
2005-06-20 22:59                                                                             ` [PATCH] Use bus_for_each_{dev,drv} for driver binding Greg KH
2005-06-20 22:59                                                                               ` [PATCH] add klist_node_attached() to determine if a node is on a list or not Greg KH
2005-06-20 22:59                                                                                 ` [PATCH] Fix up USB to use klist_node_attached() instead of list_empty() on lists that will go away Greg KH
2005-06-20 22:59                                                                                   ` [PATCH] Remove struct device::driver_list Greg KH
2005-06-20 22:59                                                                                     ` [PATCH] Fix up bus code and remove use of rwsem Greg KH
2005-06-20 22:59                                                                                       ` [PATCH] Remove struct device::bus_list Greg KH
2005-06-20 22:59                                                                                         ` [PATCH] Don't reference NULL klist pointer in klist_remove() Greg KH
2005-06-20 22:59                                                                                           ` [PATCH] Call klist_del() instead of klist_remove() Greg KH
2005-06-20 22:59                                                                                             ` [PATCH] Use device_for_each_child() to unregister devices in scsi_remove_target() Greg KH
2005-06-20 22:59                                                                                               ` [PATCH] use device_for_each_child() to properly access child devices Greg KH
2005-06-20 22:59                                                                                                 ` [PATCH] Use a klist for device child lists Greg KH
2005-06-20 22:59                                                                                                   ` [PATCH] Fix up bogus comment Greg KH
2005-06-20 22:59                                                                                                     ` [PATCH] driver core: change export symbol for driver_for_each_device() Greg KH
2005-06-20 22:59                                                                                                       ` [PATCH] Use device_for_each_child() to unregister devices in nodemgr_remove_host_dev() Greg KH
2005-06-20 22:59                                                                                                         ` [PATCH] use device_for_each_child() to properly access child devices Greg KH
2005-06-20 22:59                                                                                                           ` [PATCH] USB: fix build warning in usb core as pointed out by Andrew Greg KH
2005-06-20 22:59                                                                                                             ` [PATCH] Driver Core: fix bk-driver-core kills ppc64 Greg KH
2005-06-20 22:59                                                                                                               ` [PATCH] Fix typo in scdrv_init() Greg KH
2005-06-20 22:59                                                                                                                 ` [PATCH] Driver core: Fix up the driver and device iterators to be quieter Greg KH
2005-06-20 22:59                                                                                                                   ` [PATCH] usb: klist_node_attached() fix Greg KH
2005-06-20 22:59                                                                                                                     ` [PATCH] sn: fixes due to driver core changes Greg KH
2005-06-20 22:59                                                                                                                       ` [PATCH] driver core: Fix races in driver_detach() Greg KH
2005-06-20 22:59                                                                                                                         ` [PATCH] Driver Core: driver model doc update Greg KH
2005-06-20 22:59                                                                                                                           ` [PATCH] Driver core: unregister_node() for hotplug use Greg KH
2005-06-20 22:59                                                                                                                             ` [PATCH] usbcore: Don't call device_release_driver recursively Greg KH
2005-06-20 22:59                                                                                                                               ` Greg KH [this message]
2005-06-20 22:59                                                                                                                                 ` [PATCH] Driver core: change device_attribute callbacks Greg KH
2005-06-20 22:59                                                                                                                                   ` [PATCH] driver core: fix error handling in bus_add_device Greg KH
2005-06-20 22:59                                                                                                                                     ` [PATCH] Driver core: Documentation: update device attribute callbacks Greg KH
2005-06-20 22:59                                                                                                                                       ` [PATCH] Driver Core: drivers/base - drivers/i2c/chips/adm1026.c: " Greg KH
2005-06-20 22:59                                                                                                                                         ` [PATCH] Driver Core: arch: " Greg KH
2005-06-20 22:59                                                                                                                                           ` [PATCH] Driver Core: drivers/i2c/chips/adm1031.c - lm75.c: " Greg KH
2005-06-20 22:59                                                                                                                                             ` [PATCH] Driver Core: drivers/i2c/chips/lm77.c - max1619.c: " Greg KH
2005-06-20 22:59                                                                                                                                               ` [PATCH] Driver Core: drivers/i2c/chips/pc87360.c - w83627hf.c: " Greg KH
2005-06-20 22:59                                                                                                                                                 ` [PATCH] Driver Core: drivers/char/raw3270.c - drivers/net/netiucv.c: " Greg KH
2005-06-20 22:59                                                                                                                                                   ` [PATCH] Driver Core: drivers/i2c/chips/w83781d.c - drivers/s390/block/dcssblk.c: " Greg KH
2005-06-20 22:59                                                                                                                                                     ` [PATCH] Driver Core: drivers/usb/input/aiptek.c - drivers/zorro/zorro-sysfs.c: " Greg KH
2005-06-20 22:59                                                                                                                                                       ` [PATCH] Driver Core: drivers/s390/net/qeth_sys.c - drivers/usb/gadget/pxa2xx_udc.c: " Greg KH
2005-06-20 22:59                                                                                                                                                         ` [PATCH] Driver Core: include: " Greg KH
2005-06-20 22:59                                                                                                                                                           ` [PATCH] I2C: drivers/i2c/chips/adm1026.c: use dynamic sysfs callbacks Greg KH
2005-06-20 22:59                                                                                                                                                             ` [PATCH] I2C: add i2c sensor_device_attribute and macros Greg KH
2005-06-20 22:59                                                                                                                                                               ` [PATCH] sysfs-iattr: attach sysfs_dirent before new inode Greg KH
2005-06-20 22:59                                                                                                                                                                 ` [PATCH] Driver core: Don't "lose" devices on suspend on failure Greg KH
2005-06-20 22:59                                                                                                                                                                   ` [PATCH] sysfs-iattr: set inode attributes Greg KH
2005-06-20 22:59                                                                                                                                                                     ` [PATCH] sysfs-iattr: add sysfs_setattr Greg KH
2005-06-20 22:59                                                                                                                                                                       ` [PATCH] SYSFS: fix PAGE_SIZE check Greg KH
2005-06-20 22:59                                                                                                                                                                         ` [PATCH] USB: fix show_modalias() function due to attribute change Greg KH
2005-06-20 22:59                                                                                                                                                                           ` [PATCH] PCI: " Greg KH
2005-07-06  0:38                                                                                               ` [PATCH] Use device_for_each_child() to unregister devices in scsi_remove_target() Patrick Mansfield
2005-07-12  0:20                                                                                                 ` Greg KH
2005-07-12  0:56                                                                                                   ` Patrick Mansfield
2005-06-21 11:42                                                                         ` [PATCH] Add initial implementation of klist helpers Rik van Riel
2005-06-21 23:13                                                                           ` Greg KH
  -- strict thread matches above, loose matches on Subject: below --
2005-05-13 19:31 [PATCH 0/8] ppc64: Introduce Cell/BPA platform, v2 Arnd Bergmann
2005-05-13 19:29 ` [PATCH 7/8] ppc64: SPU file system Arnd Bergmann
2005-05-14  7:45   ` Greg KH
2005-05-18 12:40     ` [PATCH] libfs: add simple attribute files Arnd Bergmann
2005-05-18 20:24       ` Greg KH
2005-05-19  8:29         ` Arnd Bergmann
2005-06-10  4:33           ` Greg KH

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1119308367186@kroah.com \
    --to=gregkh@suse.de \
    --cc=arnd@arndb.de \
    --cc=greg@kroah.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox