Hi,

I am trying to collapse all the vectored and AIO operations
to a single set of file-operations. My initial posting, is
available here:

http://marc.theaimsgroup.com/?l=linux-kernel&m=113889673116697&w=2

As part of this work, I changed aio_read()/aio_write()
methods to take a vector, so I can drop readv/writev methods.
I was trying to fix usb/gadget/inode.c ep_aio_read()/ep_aio_write()
to support vector. I am hoping some one can help me, since I
don't understand the code well enough :( 

For my first (dumb) pass, I just loop through all the vectors.
Does this look right ? Does vectorizing these makes sense at all ?
Please let me know, how this can be optimized. (BTW, I just included
only usb/gadget related patch here - if some one wants to see the whole
thing, I can post it here).

Thanks,
Badari







===================================================================
--- linux-2.6.16-rc1.quilt.orig/Documentation/filesystems/vfs.txt	2006-02-01 16:36:55.000000000 -0800
+++ linux-2.6.16-rc1.quilt/Documentation/filesystems/vfs.txt	2006-02-01 16:38:14.000000000 -0800
@@ -526,9 +526,9 @@
 struct file_operations {
 	loff_t (*llseek) (struct file *, loff_t, int);
 	ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
-	ssize_t (*aio_read) (struct kiocb *, char __user *, size_t, loff_t);
 	ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
-	ssize_t (*aio_write) (struct kiocb *, const char __user *, size_t, loff_t);
+	ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
+	ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
 	int (*readdir) (struct file *, void *, filldir_t);
 	unsigned int (*poll) (struct file *, struct poll_table_struct *);
 	int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
Index: linux-2.6.16-rc1.quilt/drivers/usb/gadget/inode.c
===================================================================
--- linux-2.6.16-rc1.quilt.orig/drivers/usb/gadget/inode.c	2006-02-01 16:16:50.000000000 -0800
+++ linux-2.6.16-rc1.quilt/drivers/usb/gadget/inode.c	2006-02-02 16:37:46.000000000 -0800
@@ -675,36 +675,60 @@
 }
 
 static ssize_t
-ep_aio_read(struct kiocb *iocb, char __user *ubuf, size_t len, loff_t o)
+ep_aio_read(struct kiocb *iocb, const struct iovec *iv,
+		unsigned long count, loff_t o)
 {
 	struct ep_data		*epdata = iocb->ki_filp->private_data;
 	char			*buf;
+	size_t			len;
+	int			i = 0;
+	ssize_t			ret;
 
 	if (unlikely(epdata->desc.bEndpointAddress & USB_DIR_IN))
 		return -EINVAL;
-	buf = kmalloc(len, GFP_KERNEL);
-	if (unlikely(!buf))
-		return -ENOMEM;
-	iocb->ki_retry = ep_aio_read_retry;
-	return ep_aio_rwtail(iocb, buf, len, epdata, ubuf);
+
+	while (i++ < count) {
+		len = iv->iov_len;
+		buf = kmalloc(len, GFP_KERNEL);
+		if (unlikely(!buf))
+			return -ENOMEM;
+		iocb->ki_retry = ep_aio_read_retry;
+		ret = ep_aio_rwtail(iocb, buf, len, epdata, iv->iov_base);
+		if ((ret < 0) && (ret != -EIOCBQUEUED))
+			break;
+		iv++;
+	}
+	return ret;
 }
 
 static ssize_t
-ep_aio_write(struct kiocb *iocb, const char __user *ubuf, size_t len, loff_t o)
+ep_aio_write(struct kiocb *iocb, const struct iovec *iv,
+		unsigned long count, loff_t o)
 {
 	struct ep_data		*epdata = iocb->ki_filp->private_data;
 	char			*buf;
+	size_t			len;
+	int			i = 0;
+	ssize_t			ret;
 
 	if (unlikely(!(epdata->desc.bEndpointAddress & USB_DIR_IN)))
 		return -EINVAL;
-	buf = kmalloc(len, GFP_KERNEL);
-	if (unlikely(!buf))
-		return -ENOMEM;
-	if (unlikely(copy_from_user(buf, ubuf, len) != 0)) {
-		kfree(buf);
-		return -EFAULT;
+
+	while (i++ < count) {
+		len = iv->iov_len;
+		buf = kmalloc(len, GFP_KERNEL);
+		if (unlikely(!buf))
+			return -ENOMEM;
+		if (unlikely(copy_from_user(buf, iv->iov_base, len) != 0)) {
+			kfree(buf);
+			return -EFAULT;
+		}
+		ret = ep_aio_rwtail(iocb, buf, len, epdata, NULL);
+		if ((ret < 0) && (ret != -EIOCBQUEUED))
+			break;
+		iv++;
 	}
-	return ep_aio_rwtail(iocb, buf, len, epdata, NULL);
+	return ret;
 }
 
 /*----------------------------------------------------------------------*/

Reply via email to