All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chandra Seetharaman <sekharan@us.ibm.com>
To: akpm@osdl.org, Joel.Becker@oracle.com
Cc: ckrm-tech@lists.sourceforge.net, linux-kernel@vger.kernel.org,
	Chandra Seetharaman <sekharan@us.ibm.com>
Subject: [PATCH 2/5] Use seq_file for read side of operations
Date: Tue, 10 Oct 2006 11:20:55 -0700	[thread overview]
Message-ID: <20061010182055.20990.77906.sendpatchset@localhost.localdomain> (raw)
In-Reply-To: <20061010182043.20990.83892.sendpatchset@localhost.localdomain>

configfs currently has a limitation that the kernel can send only 
PAGESIZE of data through a attribute.

This patch removes that limitation by using seq_file in the read side of
operations.

Signed-Off-By: Chandra Seetharaman <sekharan@us.ibm.com>
--

 fs/configfs/file.c       |  130 ++++++++++-------------------------------------
 include/linux/configfs.h |    3 -
 2 files changed, 31 insertions(+), 102 deletions(-)

Index: linux-2.6.18/fs/configfs/file.c
===================================================================
--- linux-2.6.18.orig/fs/configfs/file.c
+++ linux-2.6.18/fs/configfs/file.c
@@ -40,112 +40,33 @@ struct configfs_buffer {
 	char			* page;
 	struct configfs_item_operations	* ops;
 	struct semaphore	sem;
-	int			needs_read_fill;
+	struct dentry		* dentry;
 };
 
 
 /**
- *	fill_read_buffer - allocate and fill buffer from item.
- *	@dentry:	dentry pointer.
- *	@buffer:	data buffer for file.
- *
- *	Allocate @buffer->page, if it hasn't been already, then call the
- *	config_item's show() method to fill the buffer with this attribute's
- *	data.
- *	This is called only once, on the file's first read.
- */
-static int fill_read_buffer(struct dentry * dentry, struct configfs_buffer * buffer)
-{
-	struct configfs_attribute * attr = to_attr(dentry);
-	struct config_item * item = to_item(dentry->d_parent);
-	struct configfs_item_operations * ops = buffer->ops;
-	int ret = 0;
-	ssize_t count;
-
-	if (!buffer->page)
-		buffer->page = (char *) get_zeroed_page(GFP_KERNEL);
-	if (!buffer->page)
-		return -ENOMEM;
-
-	count = ops->show_attribute(item,attr,buffer->page);
-	buffer->needs_read_fill = 0;
-	BUG_ON(count > (ssize_t)PAGE_SIZE);
-	if (count >= 0)
-		buffer->count = count;
-	else
-		ret = count;
-	return ret;
-}
-
-
-/**
- *	flush_read_buffer - push buffer to userspace.
- *	@buffer:	data buffer for file.
- *	@userbuf:	user-passed buffer.
- *	@count:		number of bytes requested.
- *	@ppos:		file position.
- *
- *	Copy the buffer we filled in fill_read_buffer() to userspace.
- *	This is done at the reader's leisure, copying and advancing
- *	the amount they specify each time.
- *	This may be called continuously until the buffer is empty.
- */
-static int flush_read_buffer(struct configfs_buffer * buffer, char __user * buf,
-			     size_t count, loff_t * ppos)
-{
-	int error;
-
-	if (*ppos > buffer->count)
-		return 0;
-
-	if (count > (buffer->count - *ppos))
-		count = buffer->count - *ppos;
-
-	error = copy_to_user(buf,buffer->page + *ppos,count);
-	if (!error)
-		*ppos += count;
-	return error ? -EFAULT : count;
-}
-
-/**
  *	configfs_read_file - read an attribute.
- *	@file:	file pointer.
- *	@buf:	buffer to fill.
- *	@count:	number of bytes to read.
- *	@ppos:	starting offset in file.
+ *	@s:	seq_file pointer.
+ *	@v:	unused void pointer
  *
  *	Userspace wants to read an attribute file. The attribute descriptor
- *	is in the file's ->d_fsdata. The target item is in the directory's
- *	->d_fsdata.
+ *	is available through dentry, which is stored in the seq_file.
+ *	The target item is in the dentry's parent.
+ *
+ *	We just call the show() method directly.
  *
- *	We call fill_read_buffer() to allocate and fill the buffer from the
- *	item's show() method exactly once (if the read is happening from
- *	the beginning of the file). That should fill the entire buffer with
- *	all the data the item has to offer for that attribute.
- *	We then call flush_read_buffer() to copy the buffer to userspace
- *	in the increments specified.
  */
-
-static ssize_t
-configfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos)
+static int
+configfs_read_file(struct seq_file *s, void *v)
 {
-	struct configfs_buffer * buffer = file->private_data;
-	ssize_t retval = 0;
+	struct configfs_buffer * buffer = s->private;
+	struct configfs_item_operations * ops = buffer->ops;
+	struct configfs_attribute * attr = to_attr(buffer->dentry);
+	struct config_item * item = to_item(buffer->dentry->d_parent);
 
-	down(&buffer->sem);
-	if (buffer->needs_read_fill) {
-		if ((retval = fill_read_buffer(file->f_dentry,buffer)))
-			goto out;
-	}
-	pr_debug("%s: count = %d, ppos = %lld, buf = %s\n",
-		 __FUNCTION__,count,*ppos,buffer->page);
-	retval = flush_read_buffer(buffer,buf,count,ppos);
-out:
-	up(&buffer->sem);
-	return retval;
+	return ops->show_attribute(item, attr, s);
 }
 
-
 /**
  *	fill_write_buffer - copy buffer from userspace.
  *	@buffer:	data buffer for file.
@@ -169,7 +90,6 @@ fill_write_buffer(struct configfs_buffer
 	if (count > PAGE_SIZE)
 		count = PAGE_SIZE;
 	error = copy_from_user(buffer->page,buf,count);
-	buffer->needs_read_fill = 1;
 	return error ? -EFAULT : count;
 }
 
@@ -216,7 +136,8 @@ flush_write_buffer(struct dentry * dentr
 static ssize_t
 configfs_write_file(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 {
-	struct configfs_buffer * buffer = file->private_data;
+	struct configfs_buffer * buffer =
+			((struct seq_file *)file->private_data)->private;
 	ssize_t len;
 
 	down(&buffer->sem);
@@ -281,9 +202,14 @@ static int check_perm(struct inode * ino
 	}
 	memset(buffer,0,sizeof(struct configfs_buffer));
 	init_MUTEX(&buffer->sem);
-	buffer->needs_read_fill = 1;
 	buffer->ops = ops;
-	file->private_data = buffer;
+	buffer->dentry = file->f_dentry;
+
+	error = single_open(file, configfs_read_file, buffer);
+	if (error) {
+		kfree(buffer);
+		goto Enomem;
+	}
 	goto Done;
 
  Einval:
@@ -309,7 +235,8 @@ static int configfs_release(struct inode
 	struct config_item * item = to_item(filp->f_dentry->d_parent);
 	struct configfs_attribute * attr = to_attr(filp->f_dentry);
 	struct module * owner = attr->ca_owner;
-	struct configfs_buffer * buffer = filp->private_data;
+	struct configfs_buffer * buffer =
+			((struct seq_file *)filp->private_data)->private;
 
 	if (item)
 		config_item_put(item);
@@ -321,13 +248,14 @@ static int configfs_release(struct inode
 			free_page((unsigned long)buffer->page);
 		kfree(buffer);
 	}
-	return 0;
+
+	return single_release(inode, filp);
 }
 
 const struct file_operations configfs_file_operations = {
-	.read		= configfs_read_file,
+	.read		= seq_read,
 	.write		= configfs_write_file,
-	.llseek		= generic_file_llseek,
+	.llseek		= seq_lseek,
 	.open		= configfs_open_file,
 	.release	= configfs_release,
 };
Index: linux-2.6.18/include/linux/configfs.h
===================================================================
--- linux-2.6.18.orig/include/linux/configfs.h
+++ linux-2.6.18/include/linux/configfs.h
@@ -40,6 +40,7 @@
 #include <linux/types.h>
 #include <linux/list.h>
 #include <linux/kref.h>
+#include <linux/seq_file.h>
 
 #include <asm/atomic.h>
 #include <asm/semaphore.h>
@@ -147,7 +148,7 @@ struct configfs_attribute {
  */
 struct configfs_item_operations {
 	void (*release)(struct config_item *);
-	ssize_t	(*show_attribute)(struct config_item *, struct configfs_attribute *,char *);
+	int	(*show_attribute)(struct config_item *, struct configfs_attribute *,struct seq_file *);
 	ssize_t	(*store_attribute)(struct config_item *,struct configfs_attribute *,const char *, size_t);
 	int (*allow_link)(struct config_item *src, struct config_item *target);
 	int (*drop_link)(struct config_item *src, struct config_item *target);

-- 

----------------------------------------------------------------------
    Chandra Seetharaman               | Be careful what you choose....
              - sekharan@us.ibm.com   |      .......you may get it.
----------------------------------------------------------------------

  parent reply	other threads:[~2006-10-10 18:21 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-10-10 18:20 [PATCH 0/5] Allow more than PAGESIZE data read in configfs Chandra Seetharaman
2006-10-10 18:20 ` [PATCH 1/5] Fix a module count leak Chandra Seetharaman
2006-10-10 22:17   ` Joel Becker
2006-10-10 18:20 ` Chandra Seetharaman [this message]
2006-10-11  9:12   ` [PATCH 2/5] Use seq_file for read side of operations Joel Becker
2006-10-10 18:21 ` [PATCH 3/5] Change configfs_example.c to use the new interface Chandra Seetharaman
2006-10-10 18:21 ` [PATCH 4/5] Change Documentation to reflect " Chandra Seetharaman
2006-10-10 18:21 ` [PATCH 5/5] Change the existing code to use " Chandra Seetharaman
2006-10-10 20:35 ` [PATCH 0/5] Allow more than PAGESIZE data read in configfs Joel Becker
2006-10-10 21:31   ` [ckrm-tech] " Paul Menage
2006-10-10 21:58     ` Joel Becker
2006-10-10 23:13       ` Chandra Seetharaman
2006-10-11  0:15         ` Joel Becker
2006-10-11  0:49       ` Matt Helsley
2006-10-11  1:28         ` Joel Becker
2006-10-11 22:39           ` Greg KH
2006-10-11 23:26             ` Chandra Seetharaman
2006-10-12  4:17               ` Paul Jackson
2006-10-12 23:51               ` Greg KH
2006-10-13  0:16                 ` Paul Jackson
2006-10-13 23:38                   ` Matt Helsley
2006-10-13 23:40                 ` Matt Helsley
2006-10-13 23:47                   ` Paul Menage
2006-10-14  6:17                   ` Greg KH
2006-10-14 23:14                     ` Matt Helsley
2006-10-16 19:10                 ` Chandra Seetharaman
2006-10-16 20:32                   ` Paul Jackson
2006-10-16 22:29                     ` Chandra Seetharaman
2006-10-17  2:59                       ` Paul Jackson
2006-10-12  2:17             ` Matt Helsley
2006-10-12 23:54               ` Greg KH
2006-10-13  3:22                 ` Matt Helsley
     [not found]           ` <20061011220619.GB7911@ca-server1.us.oracle.com>
     [not found]             ` <1160619516.18766.209.camel@localhost.localdomain>
2006-10-12  7:08               ` Joel Becker
2006-10-12 21:44                 ` Paul Jackson
2006-10-12 22:51                   ` Joel Becker
2006-10-13  0:01                     ` Paul Jackson
2006-10-14  4:40                       ` Greg KH
2006-10-13 23:37                 ` Matt Helsley
2006-10-14  0:09                   ` Joel Becker
2006-10-15  1:06                     ` Matt Helsley
2006-10-15 19:07                     ` Paul Jackson
2006-10-16 19:33                     ` Chandra Seetharaman
2006-10-16 23:07                       ` Joel Becker
2006-10-11 20:19   ` Andrew Morton
2006-10-11 21:41     ` Joel Becker
2006-10-11 22:18     ` Joel Becker
2006-10-11 22:48       ` Andrew Morton
2006-10-11 23:27         ` Chandra Seetharaman
2006-10-14  8:01           ` Greg KH
2006-10-14 19:43             ` Andrew Morton
2006-10-14 20:10               ` Joel Becker
2006-10-16 19:24                 ` Chandra Seetharaman
2006-10-16 23:09                   ` Joel Becker
2006-10-18  0:55                     ` Chandra Seetharaman
2006-10-19 18:42                       ` Joel Becker
2006-10-16 19:16             ` Chandra Seetharaman

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=20061010182055.20990.77906.sendpatchset@localhost.localdomain \
    --to=sekharan@us.ibm.com \
    --cc=Joel.Becker@oracle.com \
    --cc=akpm@osdl.org \
    --cc=ckrm-tech@lists.sourceforge.net \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.