Skip to contentSkip to conversation

use simple_read_from_buffer and memory_read_from_buffer

PATCH In review [email protected] 5 participants 30 messages Jun 1, 2008 – Jun 2, 2008

Subsystems (20)
lore
Share & tools
lore
#0 lore raw

cover use simple_read_from_buffer and memory_read_from_buffer

(Apologies for resending the patches due to broken email header in previous posting)

This series of patches is almost trivial replacement except for introducing memory_read_from_buffer().

The only difference between memory_read_from_buffer() and simple_read_from_buffer() is which address space the function copies to.

simple_read_from_buffer() copies to user space memory. memory_read_from_buffer() copies to normal memory.

#1 lore raw

PATCH 1/23 sunrpc: use simple_read_from_buffer

---
 net/sunrpc/cache.c |   15 +++------------
 1 file changed, 3 insertions(+), 12 deletions(-)
net/sunrpc/cache.c +3 -12
Index: 2.6-git/net/sunrpc/cache.c
===================================================================
@@ -1271,20 +1271,11 @@ static ssize_t read_flush(struct file *f
 {
 	struct cache_detail *cd = PDE(file->f_path.dentry->d_inode)->data;
 	char tbuf[20];
-	unsigned long p = *ppos;
 	size_t len;
 
-	sprintf(tbuf, "%lu\n", cd->flush_time);
-	len = strlen(tbuf);
-	if (p >= len)
-		return 0;
-	len -= p;
-	if (len > count)
-		len = count;
-	if (copy_to_user(buf, (void*)(tbuf+p), len))
-		return -EFAULT;
-	*ppos += len;
-	return len;
+	len = sprintf(tbuf, "%lu\n", cd->flush_time);
+
+	return simple_read_from_buffer(buf, count, ppos, tbuf, len);
 }
 
 static ssize_t write_flush(struct file * file, const char __user * buf,
#2 lore raw

Re: [patch -v2 01/23] sunrpc: use simple_read_from_buffer

Quoted 23 lines · On Mon, Jun 02, 2008 at 08:13:30AM +0900, [email protected] wrote:
---
 net/sunrpc/cache.c |   15 +++------------
 1 file changed, 3 insertions(+), 12 deletions(-)

Index: 2.6-git/net/sunrpc/cache.c
===================================================================

net/sunrpc/cache.c +0 -6
@@ -1271,20 +1271,11 @@ static ssize_t read_flush(struct file *f
 {
 	struct cache_detail *cd = PDE(file->f_path.dentry->d_inode)->data;
 	char tbuf[20];
-	unsigned long p = *ppos;
 	size_t len;
 
-	sprintf(tbuf, "%lu\n", cd->flush_time);
-	len = strlen(tbuf);
-	if (p >= len)
-		return 0;
-	len -= p;

net/sunrpc/cache.c static ssize_t read_flush(struct file *f · line 1279

Quoted 10 lines
net/sunrpc/cache.c +3 -6
-	if (len > count)
-		len = count;
-	if (copy_to_user(buf, (void*)(tbuf+p), len))
-		return -EFAULT;
-	*ppos += len;
-	return len;
+	len = sprintf(tbuf, "%lu\n", cd->flush_time);
+
+	return simple_read_from_buffer(buf, count, ppos, tbuf, len);
 }

Please, switch to seq_file:

	seq_printf(m, "%lu\n", cd->flush_time);
	return 0;

and that's everything module have to worry about.

#3 lore raw

Re: [patch -v2 01/23] sunrpc: use simple_read_from_buffer

Quoted 5 lines

net/sunrpc/cache.c static ssize_t read_flush(struct file *f · line 1279

Quoted 4 lines
net/sunrpc/cache.c +3 -0
+     len = sprintf(tbuf, "%lu\n", cd->flush_time);
+
+     return simple_read_from_buffer(buf, count, ppos, tbuf, len);
 }
Quoted 7 lines

Please, switch to seq_file:

       seq_printf(m, "%lu\n", cd->flush_time);
       return 0;

and that's everything module have to worry about.

OK. I'll drop this patch from the patch series. And I'll send this seq_file convertion in another chance.

#4 lore raw

PATCH 2/23 binfmt_misc: use simple_read_from_buffer

In reply to [email protected]
---
 fs/binfmt_misc.c |   20 +++-----------------
 1 file changed, 3 insertions(+), 17 deletions(-)
fs/binfmt_misc.c +3 -17
Index: 2.6-git/fs/binfmt_misc.c
===================================================================
@@ -27,6 +27,7 @@
 #include <linux/namei.h>
 #include <linux/mount.h>
 #include <linux/syscalls.h>
+#include <linux/fs.h>
 
 #include <asm/uaccess.h>
 
@@ -535,31 +536,16 @@ static ssize_t
 bm_entry_read(struct file * file, char __user * buf, size_t nbytes, loff_t *ppos)
 {
 	Node *e = file->f_path.dentry->d_inode->i_private;
-	loff_t pos = *ppos;
 	ssize_t res;
 	char *page;
-	int len;
 
 	if (!(page = (char*) __get_free_page(GFP_KERNEL)))
 		return -ENOMEM;
 
 	entry_status(e, page);
-	len = strlen(page);
 
-	res = -EINVAL;
-	if (pos < 0)
-		goto out;
-	res = 0;
-	if (pos >= len)
-		goto out;
-	if (len < pos + nbytes)
-		nbytes = len - pos;
-	res = -EFAULT;
-	if (copy_to_user(buf, page + pos, nbytes))
-		goto out;
-	*ppos = pos + nbytes;
-	res = nbytes;
-out:
+	res = simple_read_from_buffer(buf, nbytes, ppos, page, strlen(page));
+
 	free_page((unsigned long) page);
 	return res;
 }
#6 lore raw

Re: [patch -v2 03/23] ocfs2: use simple_read_from_buffer

Quoted 4 lines · akinobu.mita at gmail.com
Cc Mark Fasheh <[email protected]>
Cc Joel Becker <[email protected]>
Cc ocfs2-devel at oss.oracle.com

It looks good to my eyes, but I can't Ack it until I've had a
chance to test it.

Joel

Signature · 8 lines
"When ideas fail, words come in very handy." 
         - Goethe

Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker at oracle.com
Phone: (650) 506-8127
#7 lore raw

PATCH 4/23 ipc: use simple_read_from_buffer

In reply to [email protected]

Also this patch kills unneccesary trailing NULL character.

---
 ipc/mqueue.c |   25 +++++++------------------
 1 file changed, 7 insertions(+), 18 deletions(-)
ipc/mqueue.c +7 -18
Index: 2.6-git/ipc/mqueue.c
===================================================================
@@ -314,15 +314,11 @@ static int mqueue_unlink(struct inode *d
 *	through std routines)
 */
 static ssize_t mqueue_read_file(struct file *filp, char __user *u_data,
-				size_t count, loff_t * off)
+				size_t count, loff_t *off)
 {
 	struct mqueue_inode_info *info = MQUEUE_I(filp->f_path.dentry->d_inode);
 	char buffer[FILENT_SIZE];
-	size_t slen;
-	loff_t o;
-
-	if (!count)
-		return 0;
+	ssize_t ret;
 
 	spin_lock(&info->lock);
 	snprintf(buffer, sizeof(buffer),
@@ -335,21 +331,14 @@ static ssize_t mqueue_read_file(struct f
 			pid_vnr(info->notify_owner));
 	spin_unlock(&info->lock);
 	buffer[sizeof(buffer)-1] = '\0';
-	slen = strlen(buffer)+1;
-
-	o = *off;
-	if (o > slen)
-		return 0;
-
-	if (o + count > slen)
-		count = slen - o;
 
-	if (copy_to_user(u_data, buffer + o, count))
-		return -EFAULT;
+	ret = simple_read_from_buffer(u_data, count, off, buffer,
+				strlen(buffer));
+	if (ret <= 0)
+		return ret;
 
-	*off = o + count;
 	filp->f_path.dentry->d_inode->i_atime = filp->f_path.dentry->d_inode->i_ctime = CURRENT_TIME;
-	return count;
+	return ret;
 }
 
 static int mqueue_flush_file(struct file *filp, fl_owner_t id)
#8 lore raw

PATCH 5/23 isdn: use simple_read_from_buffer

In reply to [email protected]
---
 drivers/isdn/hysdn/hysdn_procconf.c |   27 +++++++--------------------
 1 file changed, 7 insertions(+), 20 deletions(-)
drivers/isdn/hysdn/hysdn_procconf.c +7 -20
Index: 2.6-git/drivers/isdn/hysdn/hysdn_procconf.c
===================================================================
@@ -207,30 +207,17 @@ hysdn_conf_write(struct file *file, cons
 /* read conf file -> output card info data */
 /*******************************************/
 static ssize_t
-hysdn_conf_read(struct file *file, char __user *buf, size_t count, loff_t * off)
+hysdn_conf_read(struct file *file, char __user *buf, size_t count, loff_t *off)
 {
 	char *cp;
-	int i;
 
-	if (file->f_mode & FMODE_READ) {
-		if (!(cp = file->private_data))
-			return (-EFAULT);	/* should never happen */
-		i = strlen(cp);	/* get total string length */
-		if (*off < i) {
-			/* still bytes to transfer */
-			cp += *off;	/* point to desired data offset */
-			i -= *off;	/* remaining length */
-			if (i > count)
-				i = count;	/* limit length to transfer */
-			if (copy_to_user(buf, cp, i))
-				return (-EFAULT);	/* copy error */
-			*off += i;	/* adjust offset */
-		} else
-			return (0);
-	} else
-		return (-EPERM);	/* no permission to read */
+	if (!(file->f_mode & FMODE_READ))
+		return -EPERM;	/* no permission to read */
 
-	return (i);
+	if (!(cp = file->private_data))
+		return -EFAULT;	/* should never happen */
+
+	return simple_read_from_buffer(buf, count, off, cp, strlen(cp));
 }				/* hysdn_conf_read */
 
 /******************/
#9 lore raw

PATCH 6/23 s390/vmcp: use simple_read_from_buffer

In reply to [email protected]
---
 drivers/s390/char/vmcp.c |   20 ++++++--------------
 1 file changed, 6 insertions(+), 14 deletions(-)
drivers/s390/char/vmcp.c +6 -14
Index: 2.6-git/drivers/s390/char/vmcp.c
===================================================================
@@ -61,30 +61,22 @@ static int vmcp_release(struct inode *in
 static ssize_t
 vmcp_read(struct file *file, char __user *buff, size_t count, loff_t *ppos)
 {
-	size_t tocopy;
+	ssize_t ret;
 	struct vmcp_session *session;
 
-	session = (struct vmcp_session *)file->private_data;
+	session = file->private_data;
 	if (mutex_lock_interruptible(&session->mutex))
 		return -ERESTARTSYS;
 	if (!session->response) {
 		mutex_unlock(&session->mutex);
 		return 0;
 	}
-	if (*ppos > session->resp_size) {
-		mutex_unlock(&session->mutex);
-		return 0;
-	}
-	tocopy = min(session->resp_size - (size_t) (*ppos), count);
-	tocopy = min(tocopy, session->bufsize - (size_t) (*ppos));
+	ret = simple_read_from_buffer(buff, count, ppos,
+				session->response, session->resp_size);
 
-	if (copy_to_user(buff, session->response + (*ppos), tocopy)) {
-		mutex_unlock(&session->mutex);
-		return -EFAULT;
-	}
 	mutex_unlock(&session->mutex);
-	*ppos += tocopy;
-	return tocopy;
+
+	return ret;
 }
 
 static ssize_t
#10 lore raw

Re: [patch -v2 06/23] s390/vmcp: use simple_read_from_buffer

Am Montag, 2. Juni 2008 schrieb [email protected]:

drivers/s390/char/vmcp.c static int vmcp_release(struct inode *in · line 75

Quoted 5 lines
drivers/s390/char/vmcp.c +2 -2
-	tocopy = min(session->resp_size - (size_t) (*ppos), count);
-	tocopy = min(tocopy, session->bufsize - (size_t) (*ppos));
+	ret = simple_read_from_buffer(buff, count, ppos,
+				session->response, session->resp_size);

Its not that simple. The z/VM Diagnose 8 has a quite interesting return value.

- session->bufsize is the size of the buffer as we allocated and know
- session->resp_size is the size of the data - no matter if the buffer was large enough. z/VM is smart enough to not go beyond the buffer, but it tells us how many bytes it skipped. resp_size contains bufsize + skipped_bytes.

Unfortunately there is no end of string delimiter and we have to use the response size.

There are two cases:
1. The buffer was large enough, so we can use session->resp_size
2. The buffer was not large enough and output was truncated. we must now use session->bufsize

Christian

#11 lore raw

Re: [patch -v2 06/23] s390/vmcp: use simple_read_from_buffer

2008/6/2 Christian Borntraeger <[email protected]>:

Quoted 15 lines

Am Montag, 2. Juni 2008 schrieb [email protected]:

drivers/s390/char/vmcp.c static int vmcp_release(struct inode *in · line 75

Quoted 5 lines
drivers/s390/char/vmcp.c +2 -2
-     tocopy = min(session->resp_size - (size_t) (*ppos), count);
-     tocopy = min(tocopy, session->bufsize - (size_t) (*ppos));
+     ret = simple_read_from_buffer(buff, count, ppos,
+                             session->response, session->resp_size);

Its not that simple. The z/VM Diagnose 8 has a quite interesting return value.

- session->bufsize is the size of the buffer as we allocated and know
- session->resp_size is the size of the data - no matter if the buffer was large enough. z/VM is smart enough to not go beyond the buffer, but it tells us how many bytes it skipped. resp_size contains bufsize + skipped_bytes.

Quoted 7 lines

Unfortunately there is no end of string delimiter and we have to use the response size.

There are two cases:
1. The buffer was large enough, so we can use session->resp_size
2. The buffer was not large enough and output was truncated. we must now use session->bufsize

Thanks. I made too much simplified the original code. So I'll change these lines to be

size_t size = min_t(size_t, session->resp_size, session->bufsize); ret = simple_read_from_buffer(buff, count, ppos, session->response, size);

#12 lore raw

PATCH 7/23 s390: use simple_read_from_buffer

In reply to [email protected]
---
 arch/s390/hypfs/inode.c |   29 ++++++++++-------------------
 1 file changed, 10 insertions(+), 19 deletions(-)
arch/s390/hypfs/inode.c +10 -19
Index: 2.6-git/arch/s390/hypfs/inode.c
===================================================================
@@ -150,33 +150,24 @@ static ssize_t hypfs_aio_read(struct kio
 			      unsigned long nr_segs, loff_t offset)
 {
 	char *data;
-	size_t len;
+	ssize_t ret;
 	struct file *filp = iocb->ki_filp;
 	/* XXX: temporary */
 	char __user *buf = iov[0].iov_base;
 	size_t count = iov[0].iov_len;
 
-	if (nr_segs != 1) {
-		count = -EINVAL;
-		goto out;
-	}
+	if (nr_segs != 1)
+		return -EINVAL;
 
 	data = filp->private_data;
-	len = strlen(data);
-	if (offset > len) {
-		count = 0;
-		goto out;
-	}
-	if (count > len - offset)
-		count = len - offset;
-	if (copy_to_user(buf, data + offset, count)) {
-		count = -EFAULT;
-		goto out;
-	}
-	iocb->ki_pos += count;
+	ret = simple_read_from_buffer(buf, count, &offset, data, strlen(data));
+	if (ret <= 0)
+		return ret;
+
+	iocb->ki_pos += ret;
 	file_accessed(filp);
-out:
-	return count;
+
+	return ret;
 }
 static ssize_t hypfs_aio_write(struct kiocb *iocb, const struct iovec *iov,
 			      unsigned long nr_segs, loff_t offset)
#13 lore raw

PATCH 8/23 nwflash: use simple_read_from_buffer

In reply to [email protected]
---
 drivers/char/nwflash.c |   31 ++++++++-----------------------
 1 file changed, 8 insertions(+), 23 deletions(-)
drivers/char/nwflash.c +8 -23
Index: 2.6-git/drivers/char/nwflash.c
===================================================================
@@ -122,35 +122,20 @@ static int flash_ioctl(struct inode *ino
 static ssize_t flash_read(struct file *file, char __user *buf, size_t size,
 			  loff_t *ppos)
 {
-	unsigned long p = *ppos;
-	unsigned int count = size;
-	int ret = 0;
+	ssize_t ret;
 
 	if (flashdebug)
 		printk(KERN_DEBUG "flash_read: flash_read: offset=0x%lX, "
 		       "buffer=%p, count=0x%X.\n", p, buf, count);
+	/*
+	 * We now lock against reads and writes. --rmk
+	 */
+	if (mutex_lock_interruptible(&nwflash_mutex))
+		return -ERESTARTSYS;
 
-	if (count)
-		ret = -ENXIO;
+	ret = simple_read_from_buffer(buf, size, ppos, FLASH_BASE, gbFlashSize);
+	mutex_unlock(&nwflash_mutex);
 
-	if (p < gbFlashSize) {
-		if (count > gbFlashSize - p)
-			count = gbFlashSize - p;
-
-		/*
-		 * We now lock against reads and writes. --rmk
-		 */
-		if (mutex_lock_interruptible(&nwflash_mutex))
-			return -ERESTARTSYS;
-
-		ret = copy_to_user(buf, (void *)(FLASH_BASE + p), count);
-		if (ret == 0) {
-			ret = count;
-			*ppos += count;
-		} else
-			ret = -EFAULT;
-		mutex_unlock(&nwflash_mutex);
-	}
 	return ret;
 }
 
#14 lore raw

PATCH 9/23 usbmon: use simple_read_from_buffer

In reply to [email protected]
Cc Greg Kroah-Hartman <[email protected]>
---
 drivers/usb/mon/mon_stat.c |   14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)
drivers/usb/mon/mon_stat.c +2 -12
Index: 2.6-git/drivers/usb/mon/mon_stat.c
===================================================================
@@ -9,6 +9,7 @@
 
 #include <linux/kernel.h>
 #include <linux/usb.h>
+#include <linux/fs.h>
 #include <asm/uaccess.h>
 
 #include "usb_mon.h"
@@ -42,19 +43,8 @@ static ssize_t mon_stat_read(struct file
 				size_t nbytes, loff_t *ppos)
 {
 	struct snap *sp = file->private_data;
-	loff_t pos = *ppos;
-	int cnt;
 
-	if (pos < 0 || pos >= sp->slen)
-		return 0;
-	if (nbytes == 0)
-		return 0;
-	if ((cnt = sp->slen - pos) > nbytes)
-		cnt = nbytes;
-	if (copy_to_user(buf, sp->str + pos, cnt))
-		return -EFAULT;
-	*ppos = pos + cnt;
-	return cnt;
+	return simple_read_from_buffer(buf, nbytes, ppos, sp->str, sp->slen);
 }
 
 static int mon_stat_release(struct inode *inode, struct file *file)
#15 lore raw

PATCH 10/23 ttusb: use simple_read_from_buffer()

In reply to [email protected]
---
 drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c |   18 +++---------------
 1 file changed, 3 insertions(+), 15 deletions(-)
drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +3 -15
Index: 2.6-git/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
===================================================================
@@ -19,6 +19,7 @@
 #include <linux/errno.h>
 #include <linux/jiffies.h>
 #include <linux/mutex.h>
+#include <linux/fs.h>
 
 #include "dvb_frontend.h"
 #include "dmxdev.h"
@@ -983,22 +984,9 @@ static int stc_open(struct inode *inode,
 }
 
 static ssize_t stc_read(struct file *file, char *buf, size_t count,
-		 loff_t * offset)
+		 loff_t *offset)
 {
-	int tc = count;
-
-	if ((tc + *offset) > 8192)
-		tc = 8192 - *offset;
-
-	if (tc < 0)
-		return 0;
-
-	if (copy_to_user(buf, stc_firmware + *offset, tc))
-		return -EFAULT;
-
-	*offset += tc;
-
-	return tc;
+	return simple_read_from_buffer(buf, count, offset, stc_firmware, 8192);
 }
 
 static int stc_release(struct inode *inode, struct file *file)
#16 lore raw

PATCH 11/23 airo: use simple_read_from_buffer

In reply to [email protected]
---
 drivers/net/wireless/airo.c |   15 +++------------
 1 file changed, 3 insertions(+), 12 deletions(-)
drivers/net/wireless/airo.c +3 -12
Index: 2.6-git/drivers/net/wireless/airo.c
===================================================================
@@ -4560,22 +4560,13 @@ static ssize_t proc_read( struct file *f
 			  size_t len,
 			  loff_t *offset )
 {
-	loff_t pos = *offset;
-	struct proc_data *priv = (struct proc_data*)file->private_data;
+	struct proc_data *priv = file->private_data;
 
 	if (!priv->rbuffer)
 		return -EINVAL;
 
-	if (pos < 0)
-		return -EINVAL;
-	if (pos >= priv->readlen)
-		return 0;
-	if (len > priv->readlen - pos)
-		len = priv->readlen - pos;
-	if (copy_to_user(buffer, priv->rbuffer + pos, len))
-		return -EFAULT;
-	*offset = pos + len;
-	return len;
+	return simple_read_from_buffer(buffer, len, offset, priv->rbuffer,
+					priv->readlen);
 }
 
 /*
Signature · 4 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#17 lore raw

PATCH 12/23 cris: use simple_read_from_buffer

In reply to [email protected]
---
 arch/cris/kernel/profile.c |   17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)
arch/cris/kernel/profile.c +7 -10
Index: 2.6-git/arch/cris/kernel/profile.c
===================================================================
@@ -35,19 +35,16 @@ read_cris_profile(struct file *file, cha
 		  size_t count, loff_t *ppos)
 {
 	unsigned long p = *ppos;
+	ssize_t ret;
 
-	if (p > SAMPLE_BUFFER_SIZE)
-		return 0;
+	ret = simple_read_from_buffer(buf, count, ppos, sample_buffer,
+						SAMPLE_BUFFER_SIZE);
+	if (ret < 0)
+		return ret;
 
-	if (p + count > SAMPLE_BUFFER_SIZE)
-		count = SAMPLE_BUFFER_SIZE - p;
-	if (copy_to_user(buf, sample_buffer + p,count))
-		return -EFAULT;
+	memset(sample_buffer + p, 0, ret);
 
-	memset(sample_buffer + p, 0, count);
-	*ppos += count;
-
-	return count;
+	return ret;
 }
 
 static ssize_t
#18 lore raw

PATCH 13/23 introduce memory_read_from_buffer

In reply to [email protected]

This patch introduces memory_read_from_buffer.

The only difference between memory_read_from_buffer and simple_read_from_buffer is which address space the function copies to.

simple_read_from_buffer copies to user space memory. memory_read_from_buffer copies to normal memory.

---
 fs/libfs.c         |   18 ++++++++++++++++++
 include/linux/fs.h |    5 ++++-
 2 files changed, 22 insertions(+), 1 deletion(-)
fs/libfs.c +18 -0
Index: 2.6-git/fs/libfs.c
===================================================================
@@ -528,6 +528,23 @@ ssize_t simple_read_from_buffer(void __u
 	return count;
 }
 
+ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos,
+				const void *from, size_t available)
+{
+	loff_t pos = *ppos;
+
+	if (pos < 0)
+		return -EINVAL;
+	if (pos >= available)
+		return 0;
+	if (count > available - pos)
+		count = available - pos;
+	memcpy(to, from + pos, count);
+	*ppos = pos + count;
+
+	return count;
+}
+
 /*
  * Transaction based IO.
  * The file expects a single write which triggers the transaction, and then
@@ -800,6 +817,7 @@ EXPORT_SYMBOL(simple_statfs);
 EXPORT_SYMBOL(simple_sync_file);
 EXPORT_SYMBOL(simple_unlink);
 EXPORT_SYMBOL(simple_read_from_buffer);
+EXPORT_SYMBOL(memory_read_from_buffer);
 EXPORT_SYMBOL(simple_transaction_get);
 EXPORT_SYMBOL(simple_transaction_read);
 EXPORT_SYMBOL(simple_transaction_release);
include/linux/fs.h +4 -1
Index: 2.6-git/include/linux/fs.h
===================================================================
@@ -2000,7 +2000,10 @@ extern int simple_fill_super(struct supe
 extern int simple_pin_fs(struct file_system_type *, struct vfsmount **mount, int *count);
 extern void simple_release_fs(struct vfsmount **mount, int *count);
 
-extern ssize_t simple_read_from_buffer(void __user *, size_t, loff_t *, const void *, size_t);
+extern ssize_t simple_read_from_buffer(void __user *to, size_t count,
+			loff_t *ppos, const void *from, size_t available);
+extern ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos,
+			const void *from, size_t available);
 
 #ifdef CONFIG_MIGRATION
 extern int buffer_migrate_page(struct address_space *,
#19 lore raw

PATCH 14/23 dcdbas: use memory_read_from_buffer

In reply to [email protected]
---
 drivers/firmware/dcdbas.c |   14 +++-----------
 1 file changed, 3 insertions(+), 11 deletions(-)
drivers/firmware/dcdbas.c +3 -11
Index: 2.6-git/drivers/firmware/dcdbas.c
===================================================================
@@ -34,6 +34,7 @@
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/mutex.h>
+#include <linux/fs.h>
 #include <asm/io.h>
 
 #include "dcdbas.h"
@@ -152,20 +153,11 @@ static ssize_t smi_data_read(struct kobj
 			     struct bin_attribute *bin_attr,
 			     char *buf, loff_t pos, size_t count)
 {
-	size_t max_read;
 	ssize_t ret;
 
 	mutex_lock(&smi_data_lock);
-
-	if (pos >= smi_data_buf_size) {
-		ret = 0;
-		goto out;
-	}
-
-	max_read = smi_data_buf_size - pos;
-	ret = min(max_read, count);
-	memcpy(buf, smi_data_buf + pos, ret);
-out:
+	ret = memory_read_from_buffer(buf, count, &pos, smi_data_buf,
+					smi_data_buf_size);
 	mutex_unlock(&smi_data_lock);
 	return ret;
 }
#20 lore raw

PATCH 15/23 dell_rbu: use memory_read_from_buffer

In reply to [email protected]
---
 drivers/firmware/dell_rbu.c |   29 ++++-------------------------
 1 file changed, 4 insertions(+), 25 deletions(-)
drivers/firmware/dell_rbu.c +4 -25
Index: 2.6-git/drivers/firmware/dell_rbu.c
===================================================================
@@ -44,6 +44,7 @@
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
 #include <linux/dma-mapping.h>
+#include <linux/fs.h>
 
 MODULE_AUTHOR("Abhay Salunke <[email protected]>");
 MODULE_DESCRIPTION("Driver for updating BIOS image on DELL systems");
@@ -507,11 +508,6 @@ static ssize_t read_packet_data(char *bu
 
 static ssize_t read_rbu_mono_data(char *buffer, loff_t pos, size_t count)
 {
-	unsigned char *ptemp = NULL;
-	size_t bytes_left = 0;
-	size_t data_length = 0;
-	ssize_t ret_count = 0;
-
 	/* check to see if we have something to return */
 	if ((rbu_data.image_update_buffer == NULL) ||
 		(rbu_data.bios_image_size == 0)) {
@@ -519,28 +515,11 @@ static ssize_t read_rbu_mono_data(char *
 			"bios_image_size %lu\n",
 			rbu_data.image_update_buffer,
 			rbu_data.bios_image_size);
-		ret_count = -ENOMEM;
-		goto read_rbu_data_exit;
-	}
-
-	if (pos > rbu_data.bios_image_size) {
-		ret_count = 0;
-		goto read_rbu_data_exit;
+		return -ENOMEM;
 	}
 
-	bytes_left = rbu_data.bios_image_size - pos;
-	data_length = min(bytes_left, count);
-
-	ptemp = rbu_data.image_update_buffer;
-	memcpy(buffer, (ptemp + pos), data_length);
-
-	if ((pos + count) > rbu_data.bios_image_size)
-		/* this was the last copy */
-		ret_count = bytes_left;
-	else
-		ret_count = count;
-      read_rbu_data_exit:
-	return ret_count;
+	return memory_read_from_buffer(buffer, count, &pos,
+			rbu_data.image_update_buffer, rbu_data.bios_image_size);
 }
 
 static ssize_t read_rbu_data(struct kobject *kobj,
#21 lore raw

PATCH 16/23 firmware: use memory_read_from_buffer

In reply to [email protected]
Cc Greg Kroah-Hartman <[email protected]>
---
 drivers/base/firmware_class.c |   13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)
drivers/base/firmware_class.c +4 -9
Index: 2.6-git/drivers/base/firmware_class.c
===================================================================
@@ -17,6 +17,7 @@
 #include <linux/bitops.h>
 #include <linux/mutex.h>
 #include <linux/kthread.h>
+#include <linux/fs.h>
 
 #include <linux/firmware.h>
 #include "base.h"
@@ -176,7 +177,7 @@ firmware_data_read(struct kobject *kobj,
 	struct device *dev = to_dev(kobj);
 	struct firmware_priv *fw_priv = dev_get_drvdata(dev);
 	struct firmware *fw;
-	ssize_t ret_count = count;
+	ssize_t ret_count;
 
 	mutex_lock(&fw_lock);
 	fw = fw_priv->fw;
@@ -184,14 +185,8 @@ firmware_data_read(struct kobject *kobj,
 		ret_count = -ENODEV;
 		goto out;
 	}
-	if (offset > fw->size) {
-		ret_count = 0;
-		goto out;
-	}
-	if (offset + ret_count > fw->size)
-		ret_count = fw->size - offset;
-
-	memcpy(buffer, fw->data + offset, ret_count);
+	ret_count = memory_read_from_buffer(buffer, count, &offset,
+						fw->data, fw->size);
 out:
 	mutex_unlock(&fw_lock);
 	return ret_count;
#22 lore raw

PATCH 17/23 acpi: use memory_read_from_buffer

In reply to [email protected]
---
 drivers/acpi/system.c |   15 ++-------------
 1 file changed, 2 insertions(+), 13 deletions(-)
drivers/acpi/system.c +2 -13
Index: 2.6-git/drivers/acpi/system.c
===================================================================
@@ -77,7 +77,6 @@ static ssize_t acpi_table_show(struct ko
 	    container_of(bin_attr, struct acpi_table_attr, attr);
 	struct acpi_table_header *table_header = NULL;
 	acpi_status status;
-	ssize_t ret_count = count;
 
 	status =
 	    acpi_get_table(table_attr->name, table_attr->instance,
@@ -85,18 +84,8 @@ static ssize_t acpi_table_show(struct ko
 	if (ACPI_FAILURE(status))
 		return -ENODEV;
 
-	if (offset >= table_header->length) {
-		ret_count = 0;
-		goto end;
-	}
-
-	if (offset + ret_count > table_header->length)
-		ret_count = table_header->length - offset;
-
-	memcpy(buf, ((char *)table_header) + offset, ret_count);
-
-      end:
-	return ret_count;
+	return memory_read_from_buffer(buf, count, &offset,
+					table_header, table_header->length);
 }
 
 static void acpi_table_attr_init(struct acpi_table_attr *table_attr,
#23 lore raw

PATCH 18/23 aty: use memory_read_from_buffer

In reply to [email protected]
---
 drivers/video/aty/radeon_base.c |   11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)
drivers/video/aty/radeon_base.c +2 -9
Index: 2.6-git/drivers/video/aty/radeon_base.c
===================================================================
@@ -70,6 +70,7 @@
 #include <linux/pci.h>
 #include <linux/vmalloc.h>
 #include <linux/device.h>
+#include <linux/fs.h>
 
 #include <asm/io.h>
 #include <linux/uaccess.h>
@@ -2098,15 +2099,7 @@ static void radeon_identify_vram(struct 
 
 static ssize_t radeon_show_one_edid(char *buf, loff_t off, size_t count, const u8 *edid)
 {
-	if (off > EDID_LENGTH)
-		return 0;
-
-	if (off + count > EDID_LENGTH)
-		count = EDID_LENGTH - off;
-
-	memcpy(buf, edid + off, count);
-
-	return count;
+	return memory_read_from_buffer(buf, count, &off, edid, EDID_LENGTH);
 }
 
 
Signature · 4 lines
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
#24 lore raw

PATCH 19/23 zorro: use memory_read_from_buffer

In reply to [email protected]
Cc Geert Uytterhoeven <[email protected]>
---
 drivers/zorro/zorro-sysfs.c |   10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)
drivers/zorro/zorro-sysfs.c +2 -8
Index: 2.6-git/drivers/zorro/zorro-sysfs.c
===================================================================
@@ -15,6 +15,7 @@
 #include <linux/zorro.h>
 #include <linux/stat.h>
 #include <linux/string.h>
+#include <linux/fs.h>
 
 #include "zorro.h"
 
@@ -56,12 +57,6 @@ static ssize_t zorro_read_config(struct 
 	struct zorro_dev *z = to_zorro_dev(container_of(kobj, struct device,
 					   kobj));
 	struct ConfigDev cd;
-	unsigned int size = sizeof(cd);
-
-	if (off > size)
-		return 0;
-	if (off+count > size)
-		count = size-off;
 
 	/* Construct a ConfigDev */
 	memset(&cd, 0, sizeof(cd));
@@ -71,8 +66,7 @@ static ssize_t zorro_read_config(struct 
 	cd.cd_BoardAddr = (void *)zorro_resource_start(z);
 	cd.cd_BoardSize = zorro_resource_len(z);
 
-	memcpy(buf, (void *)&cd+off, count);
-	return count;
+	return memory_read_from_buffer(buf, count, &off, &cd, sizeof(cd));
 }
 
 static struct bin_attribute zorro_config_attr = {
maintainer Acked-by on v1 19/23
#25 lore raw

Re: [patch -v2 19/23] zorro: use memory_read_from_buffer

Quoted 2 lines · On Mon, 2 Jun 2008, [email protected] wrote:
Cc Geert Uytterhoeven <[email protected]>
Quoted 30 lines
---
 drivers/zorro/zorro-sysfs.c |   10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

Index: 2.6-git/drivers/zorro/zorro-sysfs.c
===================================================================

drivers/zorro/zorro-sysfs.c +1 -6
@@ -15,6 +15,7 @@
 #include <linux/zorro.h>
 #include <linux/stat.h>
 #include <linux/string.h>
+#include <linux/fs.h>
 
 #include "zorro.h"
 
@@ -56,12 +57,6 @@ static ssize_t zorro_read_config(struct 
 	struct zorro_dev *z = to_zorro_dev(container_of(kobj, struct device,
 					   kobj));
 	struct ConfigDev cd;
-	unsigned int size = sizeof(cd);
-
-	if (off > size)
-		return 0;
-	if (off+count > size)
-		count = size-off;
 
 	/* Construct a ConfigDev */
 	memset(&cd, 0, sizeof(cd));

drivers/zorro/zorro-sysfs.c static ssize_t zorro_read_config(struct · line 72

Quoted 9 lines
drivers/zorro/zorro-sysfs.c +1 -2
@@ -71,8 +66,7 @@ static ssize_t zorro_read_config(struct 
 	cd.cd_BoardAddr = (void *)zorro_resource_start(z);
 	cd.cd_BoardSize = zorro_resource_len(z);
 
-	memcpy(buf, (void *)&cd+off, count);
-	return count;
+	return memory_read_from_buffer(buf, count, &off, &cd, sizeof(cd));
 }
 
 static struct bin_attribute zorro_config_attr = {

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

#26 lore raw

PATCH 20/23 s390/cio: use memory_read_from_buffer

In reply to [email protected]
---
 drivers/s390/cio/chp.c |   12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)
drivers/s390/cio/chp.c +3 -9
Index: 2.6-git/drivers/s390/cio/chp.c
===================================================================
@@ -15,6 +15,7 @@
 #include <linux/wait.h>
 #include <linux/mutex.h>
 #include <linux/errno.h>
+#include <linux/fs.h>
 #include <asm/chpid.h>
 #include <asm/sclp.h>
 
@@ -141,21 +142,14 @@ static ssize_t chp_measurement_chars_rea
 {
 	struct channel_path *chp;
 	struct device *device;
-	unsigned int size;
 
 	device = container_of(kobj, struct device, kobj);
 	chp = to_channelpath(device);
 	if (!chp->cmg_chars)
 		return 0;
 
-	size = sizeof(struct cmg_chars);
-
-	if (off > size)
-		return 0;
-	if (off + count > size)
-		count = size - off;
-	memcpy(buf, chp->cmg_chars + off, count);
-	return count;
+	return memory_read_from_buffer(buf, count, &off,
+				chp->cmg_chars, sizeof(struct cmg_chars));
 }
 
 static struct bin_attribute chp_measurement_chars_attr = {
#27 lore raw

PATCH 21/23 s390: use memory_read_from_buffer

In reply to [email protected]
---
 arch/s390/kernel/ipl.c |   18 ++++--------------
 1 file changed, 4 insertions(+), 14 deletions(-)
arch/s390/kernel/ipl.c +4 -14
Index: 2.6-git/arch/s390/kernel/ipl.c
===================================================================
@@ -14,6 +14,7 @@
 #include <linux/delay.h>
 #include <linux/reboot.h>
 #include <linux/ctype.h>
+#include <linux/fs.h>
 #include <asm/ipl.h>
 #include <asm/smp.h>
 #include <asm/setup.h>
@@ -285,14 +286,8 @@ static struct kobj_attribute sys_ipl_dev
 static ssize_t ipl_parameter_read(struct kobject *kobj, struct bin_attribute *attr,
 				  char *buf, loff_t off, size_t count)
 {
-	unsigned int size = IPL_PARMBLOCK_SIZE;
-
-	if (off > size)
-		return 0;
-	if (off + count > size)
-		count = size - off;
-	memcpy(buf, (void *)IPL_PARMBLOCK_START + off, count);
-	return count;
+	return memory_read_from_buffer(buf, count, &off, IPL_PARMBLOCK_START,
+					IPL_PARMBLOCK_SIZE);
 }
 
 static struct bin_attribute ipl_parameter_attr = {
@@ -310,12 +305,7 @@ static ssize_t ipl_scp_data_read(struct 
 	unsigned int size = IPL_PARMBLOCK_START->ipl_info.fcp.scp_data_len;
 	void *scp_data = &IPL_PARMBLOCK_START->ipl_info.fcp.scp_data;
 
-	if (off > size)
-		return 0;
-	if (off + count > size)
-		count = size - off;
-	memcpy(buf, scp_data + off, count);
-	return count;
+	return memory_read_from_buffer(buf, count, &off, scp_data, size);
 }
 
 static struct bin_attribute ipl_scp_data_attr = {
#28 lore raw

PATCH 22/23 ipr: use memory_read_from_buffer

In reply to [email protected]
Cc Brian King <[email protected]>
Cc James E.J. Bottomley <[email protected]>
---
 drivers/scsi/ipr.c |   16 +++++-----------
 1 file changed, 5 insertions(+), 11 deletions(-)
drivers/scsi/ipr.c +5 -11
Index: 2.6-git/drivers/scsi/ipr.c
===================================================================
@@ -2455,20 +2455,14 @@ static ssize_t ipr_read_trace(struct kob
 	struct Scsi_Host *shost = class_to_shost(dev);
 	struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)shost->hostdata;
 	unsigned long lock_flags = 0;
-	int size = IPR_TRACE_SIZE;
-	char *src = (char *)ioa_cfg->trace;
-
-	if (off > size)
-		return 0;
-	if (off + count > size) {
-		size -= off;
-		count = size;
-	}
+	ssize_t ret;
 
 	spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
-	memcpy(buf, &src[off], count);
+	ret = memory_read_from_buffer(buf, count, &off, ioa_cfg->trace,
+				IPR_TRACE_SIZE);
 	spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
-	return count;
+
+	return ret;
 }
 
 static struct bin_attribute ipr_trace_attr = {
#29 lore raw

PATCH 23/23 qla2xxx: use memory_read_from_buffer

In reply to [email protected]
Cc Andrew Vasquez <[email protected]>
Cc James E.J. Bottomley <[email protected]>
---
 drivers/scsi/qla2xxx/qla_attr.c |   45 ++++++++--------------------------------
 1 file changed, 10 insertions(+), 35 deletions(-)
drivers/scsi/qla2xxx/qla_attr.c +10 -35
Index: 2.6-git/drivers/scsi/qla2xxx/qla_attr.c
===================================================================
@@ -8,6 +8,7 @@
 
 #include <linux/kthread.h>
 #include <linux/vmalloc.h>
+#include <linux/fs.h>
 
 static int qla24xx_vport_disable(struct fc_vport *, bool);
 
@@ -20,18 +21,12 @@ qla2x00_sysfs_read_fw_dump(struct kobjec
 {
 	struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj,
 	    struct device, kobj)));
-	char *rbuf = (char *)ha->fw_dump;
 
 	if (ha->fw_dump_reading == 0)
 		return 0;
-	if (off > ha->fw_dump_len)
-                return 0;
-	if (off + count > ha->fw_dump_len)
-		count = ha->fw_dump_len - off;
 
-	memcpy(buf, &rbuf[off], count);
-
-	return (count);
+	return memory_read_from_buffer(buf, count, &off, ha->fw_dump,
+					ha->fw_dump_len);
 }
 
 static ssize_t
@@ -91,20 +86,13 @@ qla2x00_sysfs_read_nvram(struct kobject 
 {
 	struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj,
 	    struct device, kobj)));
-	int		size = ha->nvram_size;
-	char		*nvram_cache = ha->nvram;
 
-	if (!capable(CAP_SYS_ADMIN) || off > size || count == 0)
+	if (!capable(CAP_SYS_ADMIN))
 		return 0;
-	if (off + count > size) {
-		size -= off;
-		count = size;
-	}
 
 	/* Read NVRAM data from cache. */
-	memcpy(buf, &nvram_cache[off], count);
-
-	return count;
+	return memory_read_from_buffer(buf, count, &off, ha->nvram,
+					ha->nvram_size);
 }
 
 static ssize_t
@@ -172,14 +160,9 @@ qla2x00_sysfs_read_optrom(struct kobject
 
 	if (ha->optrom_state != QLA_SREADING)
 		return 0;
-	if (off > ha->optrom_region_size)
-		return 0;
-	if (off + count > ha->optrom_region_size)
-		count = ha->optrom_region_size - off;
 
-	memcpy(buf, &ha->optrom_buffer[off], count);
-
-	return count;
+	return memory_read_from_buffer(buf, count, &off, ha->optrom_buffer,
+					ha->optrom_region_size);
 }
 
 static ssize_t
@@ -371,20 +354,12 @@ qla2x00_sysfs_read_vpd(struct kobject *k
 {
 	struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj,
 	    struct device, kobj)));
-	int           size = ha->vpd_size;
-	char          *vpd_cache = ha->vpd;
 
-	if (!capable(CAP_SYS_ADMIN) || off > size || count == 0)
+	if (!capable(CAP_SYS_ADMIN))
 		return 0;
-	if (off + count > size) {
-		size -= off;
-		count = size;
-	}
 
 	/* Read NVRAM data from cache. */
-	memcpy(buf, &vpd_cache[off], count);
-
-	return count;
+	return memory_read_from_buffer(buf, count, &off, ha->vpd, ha->vpd_size);
 }
 
 static ssize_t