aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorBadari Pulavarty <pbadari@us.ibm.com>2006-10-01 02:28:46 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-01 03:39:28 -0400
commit027445c37282bc1ed26add45e573ad2d3e4860a5 (patch)
tree93eab101a938ffebaea64703033c8649df4d73f0 /fs
parent9ea0f9499d15c49df23e7aac4332d830c40e12d0 (diff)
[PATCH] Vectorize aio_read/aio_write fileop methods
This patch vectorizes aio_read() and aio_write() methods to prepare for collapsing all aio & vectored operations into one interface - which is aio_read()/aio_write(). Signed-off-by: Badari Pulavarty <pbadari@us.ibm.com> Signed-off-by: Christoph Hellwig <hch@lst.de> Cc: Michael Holzheu <HOLZHEU@de.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/aio.c15
-rw-r--r--fs/block_dev.c10
-rw-r--r--fs/cifs/cifsfs.c6
-rw-r--r--fs/ext3/file.c5
-rw-r--r--fs/nfs/direct.c26
-rw-r--r--fs/nfs/file.c34
-rw-r--r--fs/ntfs/file.c8
-rw-r--r--fs/ocfs2/file.c28
-rw-r--r--fs/read_write.c20
-rw-r--r--fs/reiserfs/file.c4
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c46
11 files changed, 113 insertions, 89 deletions
diff --git a/fs/aio.c b/fs/aio.c
index 950630187acc..27ff56540c73 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -15,6 +15,7 @@
15#include <linux/aio_abi.h> 15#include <linux/aio_abi.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/syscalls.h> 17#include <linux/syscalls.h>
18#include <linux/uio.h>
18 19
19#define DEBUG 0 20#define DEBUG 0
20 21
@@ -1315,8 +1316,11 @@ static ssize_t aio_pread(struct kiocb *iocb)
1315 ssize_t ret = 0; 1316 ssize_t ret = 0;
1316 1317
1317 do { 1318 do {
1318 ret = file->f_op->aio_read(iocb, iocb->ki_buf, 1319 iocb->ki_inline_vec.iov_base = iocb->ki_buf;
1319 iocb->ki_left, iocb->ki_pos); 1320 iocb->ki_inline_vec.iov_len = iocb->ki_left;
1321
1322 ret = file->f_op->aio_read(iocb, &iocb->ki_inline_vec,
1323 1, iocb->ki_pos);
1320 /* 1324 /*
1321 * Can't just depend on iocb->ki_left to determine 1325 * Can't just depend on iocb->ki_left to determine
1322 * whether we are done. This may have been a short read. 1326 * whether we are done. This may have been a short read.
@@ -1349,8 +1353,11 @@ static ssize_t aio_pwrite(struct kiocb *iocb)
1349 ssize_t ret = 0; 1353 ssize_t ret = 0;
1350 1354
1351 do { 1355 do {
1352 ret = file->f_op->aio_write(iocb, iocb->ki_buf, 1356 iocb->ki_inline_vec.iov_base = iocb->ki_buf;
1353 iocb->ki_left, iocb->ki_pos); 1357 iocb->ki_inline_vec.iov_len = iocb->ki_left;
1358
1359 ret = file->f_op->aio_write(iocb, &iocb->ki_inline_vec,
1360 1, iocb->ki_pos);
1354 if (ret > 0) { 1361 if (ret > 0) {
1355 iocb->ki_buf += ret; 1362 iocb->ki_buf += ret;
1356 iocb->ki_left -= ret; 1363 iocb->ki_left -= ret;
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 0c361ea7e5a6..8c819117310b 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1162,14 +1162,6 @@ static ssize_t blkdev_file_write(struct file *file, const char __user *buf,
1162 return generic_file_write_nolock(file, &local_iov, 1, ppos); 1162 return generic_file_write_nolock(file, &local_iov, 1, ppos);
1163} 1163}
1164 1164
1165static ssize_t blkdev_file_aio_write(struct kiocb *iocb, const char __user *buf,
1166 size_t count, loff_t pos)
1167{
1168 struct iovec local_iov = { .iov_base = (void __user *)buf, .iov_len = count };
1169
1170 return generic_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos);
1171}
1172
1173static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg) 1165static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg)
1174{ 1166{
1175 return blkdev_ioctl(file->f_mapping->host, file, cmd, arg); 1167 return blkdev_ioctl(file->f_mapping->host, file, cmd, arg);
@@ -1192,7 +1184,7 @@ const struct file_operations def_blk_fops = {
1192 .read = generic_file_read, 1184 .read = generic_file_read,
1193 .write = blkdev_file_write, 1185 .write = blkdev_file_write,
1194 .aio_read = generic_file_aio_read, 1186 .aio_read = generic_file_aio_read,
1195 .aio_write = blkdev_file_aio_write, 1187 .aio_write = generic_file_aio_write_nolock,
1196 .mmap = generic_file_mmap, 1188 .mmap = generic_file_mmap,
1197 .fsync = block_fsync, 1189 .fsync = block_fsync,
1198 .unlocked_ioctl = block_ioctl, 1190 .unlocked_ioctl = block_ioctl,
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 22bcf4d7e7ae..5abb42a7c53e 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -492,13 +492,13 @@ static ssize_t cifs_file_writev(struct file *file, const struct iovec *iov,
492 return written; 492 return written;
493} 493}
494 494
495static ssize_t cifs_file_aio_write(struct kiocb *iocb, const char __user *buf, 495static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
496 size_t count, loff_t pos) 496 unsigned long nr_segs, loff_t pos)
497{ 497{
498 struct inode *inode = iocb->ki_filp->f_dentry->d_inode; 498 struct inode *inode = iocb->ki_filp->f_dentry->d_inode;
499 ssize_t written; 499 ssize_t written;
500 500
501 written = generic_file_aio_write(iocb, buf, count, pos); 501 written = generic_file_aio_write(iocb, iov, nr_segs, pos);
502 if (!CIFS_I(inode)->clientCanCacheAll) 502 if (!CIFS_I(inode)->clientCanCacheAll)
503 filemap_fdatawrite(inode->i_mapping); 503 filemap_fdatawrite(inode->i_mapping);
504 return written; 504 return written;
diff --git a/fs/ext3/file.c b/fs/ext3/file.c
index 74ff20f9d09b..5c762457bc89 100644
--- a/fs/ext3/file.c
+++ b/fs/ext3/file.c
@@ -48,14 +48,15 @@ static int ext3_release_file (struct inode * inode, struct file * filp)
48} 48}
49 49
50static ssize_t 50static ssize_t
51ext3_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos) 51ext3_file_write(struct kiocb *iocb, const struct iovec *iov,
52 unsigned long nr_segs, loff_t pos)
52{ 53{
53 struct file *file = iocb->ki_filp; 54 struct file *file = iocb->ki_filp;
54 struct inode *inode = file->f_dentry->d_inode; 55 struct inode *inode = file->f_dentry->d_inode;
55 ssize_t ret; 56 ssize_t ret;
56 int err; 57 int err;
57 58
58 ret = generic_file_aio_write(iocb, buf, count, pos); 59 ret = generic_file_aio_write(iocb, iov, nr_segs, pos);
59 60
60 /* 61 /*
61 * Skip flushing if there was an error, or if nothing was written. 62 * Skip flushing if there was an error, or if nothing was written.
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 377839bed172..9f7f8b9ea1e2 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -707,8 +707,8 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, unsigned long user_addr, siz
707/** 707/**
708 * nfs_file_direct_read - file direct read operation for NFS files 708 * nfs_file_direct_read - file direct read operation for NFS files
709 * @iocb: target I/O control block 709 * @iocb: target I/O control block
710 * @buf: user's buffer into which to read data 710 * @iov: vector of user buffers into which to read data
711 * @count: number of bytes to read 711 * @nr_segs: size of iov vector
712 * @pos: byte offset in file where reading starts 712 * @pos: byte offset in file where reading starts
713 * 713 *
714 * We use this function for direct reads instead of calling 714 * We use this function for direct reads instead of calling
@@ -725,17 +725,24 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, unsigned long user_addr, siz
725 * client must read the updated atime from the server back into its 725 * client must read the updated atime from the server back into its
726 * cache. 726 * cache.
727 */ 727 */
728ssize_t nfs_file_direct_read(struct kiocb *iocb, char __user *buf, size_t count, loff_t pos) 728ssize_t nfs_file_direct_read(struct kiocb *iocb, const struct iovec *iov,
729 unsigned long nr_segs, loff_t pos)
729{ 730{
730 ssize_t retval = -EINVAL; 731 ssize_t retval = -EINVAL;
731 struct file *file = iocb->ki_filp; 732 struct file *file = iocb->ki_filp;
732 struct address_space *mapping = file->f_mapping; 733 struct address_space *mapping = file->f_mapping;
734 /* XXX: temporary */
735 const char __user *buf = iov[0].iov_base;
736 size_t count = iov[0].iov_len;
733 737
734 dprintk("nfs: direct read(%s/%s, %lu@%Ld)\n", 738 dprintk("nfs: direct read(%s/%s, %lu@%Ld)\n",
735 file->f_dentry->d_parent->d_name.name, 739 file->f_dentry->d_parent->d_name.name,
736 file->f_dentry->d_name.name, 740 file->f_dentry->d_name.name,
737 (unsigned long) count, (long long) pos); 741 (unsigned long) count, (long long) pos);
738 742
743 if (nr_segs != 1)
744 return -EINVAL;
745
739 if (count < 0) 746 if (count < 0)
740 goto out; 747 goto out;
741 retval = -EFAULT; 748 retval = -EFAULT;
@@ -760,8 +767,8 @@ out:
760/** 767/**
761 * nfs_file_direct_write - file direct write operation for NFS files 768 * nfs_file_direct_write - file direct write operation for NFS files
762 * @iocb: target I/O control block 769 * @iocb: target I/O control block
763 * @buf: user's buffer from which to write data 770 * @iov: vector of user buffers from which to write data
764 * @count: number of bytes to write 771 * @nr_segs: size of iov vector
765 * @pos: byte offset in file where writing starts 772 * @pos: byte offset in file where writing starts
766 * 773 *
767 * We use this function for direct writes instead of calling 774 * We use this function for direct writes instead of calling
@@ -782,17 +789,24 @@ out:
782 * Note that O_APPEND is not supported for NFS direct writes, as there 789 * Note that O_APPEND is not supported for NFS direct writes, as there
783 * is no atomic O_APPEND write facility in the NFS protocol. 790 * is no atomic O_APPEND write facility in the NFS protocol.
784 */ 791 */
785ssize_t nfs_file_direct_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos) 792ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov,
793 unsigned long nr_segs, loff_t pos)
786{ 794{
787 ssize_t retval; 795 ssize_t retval;
788 struct file *file = iocb->ki_filp; 796 struct file *file = iocb->ki_filp;
789 struct address_space *mapping = file->f_mapping; 797 struct address_space *mapping = file->f_mapping;
798 /* XXX: temporary */
799 const char __user *buf = iov[0].iov_base;
800 size_t count = iov[0].iov_len;
790 801
791 dfprintk(VFS, "nfs: direct write(%s/%s, %lu@%Ld)\n", 802 dfprintk(VFS, "nfs: direct write(%s/%s, %lu@%Ld)\n",
792 file->f_dentry->d_parent->d_name.name, 803 file->f_dentry->d_parent->d_name.name,
793 file->f_dentry->d_name.name, 804 file->f_dentry->d_name.name,
794 (unsigned long) count, (long long) pos); 805 (unsigned long) count, (long long) pos);
795 806
807 if (nr_segs != 1)
808 return -EINVAL;
809
796 retval = generic_write_checks(file, &pos, &count, 0); 810 retval = generic_write_checks(file, &pos, &count, 0);
797 if (retval) 811 if (retval)
798 goto out; 812 goto out;
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index be997d649127..cc93865cea93 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -41,8 +41,10 @@ static int nfs_file_release(struct inode *, struct file *);
41static loff_t nfs_file_llseek(struct file *file, loff_t offset, int origin); 41static loff_t nfs_file_llseek(struct file *file, loff_t offset, int origin);
42static int nfs_file_mmap(struct file *, struct vm_area_struct *); 42static int nfs_file_mmap(struct file *, struct vm_area_struct *);
43static ssize_t nfs_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *); 43static ssize_t nfs_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *);
44static ssize_t nfs_file_read(struct kiocb *, char __user *, size_t, loff_t); 44static ssize_t nfs_file_read(struct kiocb *, const struct iovec *iov,
45static ssize_t nfs_file_write(struct kiocb *, const char __user *, size_t, loff_t); 45 unsigned long nr_segs, loff_t pos);
46static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov,
47 unsigned long nr_segs, loff_t pos);
46static int nfs_file_flush(struct file *, fl_owner_t id); 48static int nfs_file_flush(struct file *, fl_owner_t id);
47static int nfs_fsync(struct file *, struct dentry *dentry, int datasync); 49static int nfs_fsync(struct file *, struct dentry *dentry, int datasync);
48static int nfs_check_flags(int flags); 50static int nfs_check_flags(int flags);
@@ -53,8 +55,8 @@ const struct file_operations nfs_file_operations = {
53 .llseek = nfs_file_llseek, 55 .llseek = nfs_file_llseek,
54 .read = do_sync_read, 56 .read = do_sync_read,
55 .write = do_sync_write, 57 .write = do_sync_write,
56 .aio_read = nfs_file_read, 58 .aio_read = nfs_file_read,
57 .aio_write = nfs_file_write, 59 .aio_write = nfs_file_write,
58 .mmap = nfs_file_mmap, 60 .mmap = nfs_file_mmap,
59 .open = nfs_file_open, 61 .open = nfs_file_open,
60 .flush = nfs_file_flush, 62 .flush = nfs_file_flush,
@@ -196,15 +198,17 @@ nfs_file_flush(struct file *file, fl_owner_t id)
196} 198}
197 199
198static ssize_t 200static ssize_t
199nfs_file_read(struct kiocb *iocb, char __user * buf, size_t count, loff_t pos) 201nfs_file_read(struct kiocb *iocb, const struct iovec *iov,
202 unsigned long nr_segs, loff_t pos)
200{ 203{
201 struct dentry * dentry = iocb->ki_filp->f_dentry; 204 struct dentry * dentry = iocb->ki_filp->f_dentry;
202 struct inode * inode = dentry->d_inode; 205 struct inode * inode = dentry->d_inode;
203 ssize_t result; 206 ssize_t result;
207 size_t count = iov_length(iov, nr_segs);
204 208
205#ifdef CONFIG_NFS_DIRECTIO 209#ifdef CONFIG_NFS_DIRECTIO
206 if (iocb->ki_filp->f_flags & O_DIRECT) 210 if (iocb->ki_filp->f_flags & O_DIRECT)
207 return nfs_file_direct_read(iocb, buf, count, pos); 211 return nfs_file_direct_read(iocb, iov, nr_segs, pos);
208#endif 212#endif
209 213
210 dfprintk(VFS, "nfs: read(%s/%s, %lu@%lu)\n", 214 dfprintk(VFS, "nfs: read(%s/%s, %lu@%lu)\n",
@@ -214,7 +218,7 @@ nfs_file_read(struct kiocb *iocb, char __user * buf, size_t count, loff_t pos)
214 result = nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping); 218 result = nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping);
215 nfs_add_stats(inode, NFSIOS_NORMALREADBYTES, count); 219 nfs_add_stats(inode, NFSIOS_NORMALREADBYTES, count);
216 if (!result) 220 if (!result)
217 result = generic_file_aio_read(iocb, buf, count, pos); 221 result = generic_file_aio_read(iocb, iov, nr_segs, pos);
218 return result; 222 return result;
219} 223}
220 224
@@ -336,24 +340,22 @@ const struct address_space_operations nfs_file_aops = {
336#endif 340#endif
337}; 341};
338 342
339/* 343static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov,
340 * Write to a file (through the page cache). 344 unsigned long nr_segs, loff_t pos)
341 */
342static ssize_t
343nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos)
344{ 345{
345 struct dentry * dentry = iocb->ki_filp->f_dentry; 346 struct dentry * dentry = iocb->ki_filp->f_dentry;
346 struct inode * inode = dentry->d_inode; 347 struct inode * inode = dentry->d_inode;
347 ssize_t result; 348 ssize_t result;
349 size_t count = iov_length(iov, nr_segs);
348 350
349#ifdef CONFIG_NFS_DIRECTIO 351#ifdef CONFIG_NFS_DIRECTIO
350 if (iocb->ki_filp->f_flags & O_DIRECT) 352 if (iocb->ki_filp->f_flags & O_DIRECT)
351 return nfs_file_direct_write(iocb, buf, count, pos); 353 return nfs_file_direct_write(iocb, iov, nr_segs, pos);
352#endif 354#endif
353 355
354 dfprintk(VFS, "nfs: write(%s/%s(%ld), %lu@%lu)\n", 356 dfprintk(VFS, "nfs: write(%s/%s(%ld), %lu@%Ld)\n",
355 dentry->d_parent->d_name.name, dentry->d_name.name, 357 dentry->d_parent->d_name.name, dentry->d_name.name,
356 inode->i_ino, (unsigned long) count, (unsigned long) pos); 358 inode->i_ino, (unsigned long) count, (long long) pos);
357 359
358 result = -EBUSY; 360 result = -EBUSY;
359 if (IS_SWAPFILE(inode)) 361 if (IS_SWAPFILE(inode))
@@ -372,7 +374,7 @@ nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t
372 goto out; 374 goto out;
373 375
374 nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count); 376 nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count);
375 result = generic_file_aio_write(iocb, buf, count, pos); 377 result = generic_file_aio_write(iocb, iov, nr_segs, pos);
376out: 378out:
377 return result; 379 return result;
378 380
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index 585a79d39c9d..0c46f5c86b71 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -2176,20 +2176,18 @@ out:
2176/** 2176/**
2177 * ntfs_file_aio_write - 2177 * ntfs_file_aio_write -
2178 */ 2178 */
2179static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const char __user *buf, 2179static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
2180 size_t count, loff_t pos) 2180 unsigned long nr_segs, loff_t pos)
2181{ 2181{
2182 struct file *file = iocb->ki_filp; 2182 struct file *file = iocb->ki_filp;
2183 struct address_space *mapping = file->f_mapping; 2183 struct address_space *mapping = file->f_mapping;
2184 struct inode *inode = mapping->host; 2184 struct inode *inode = mapping->host;
2185 ssize_t ret; 2185 ssize_t ret;
2186 struct iovec local_iov = { .iov_base = (void __user *)buf,
2187 .iov_len = count };
2188 2186
2189 BUG_ON(iocb->ki_pos != pos); 2187 BUG_ON(iocb->ki_pos != pos);
2190 2188
2191 mutex_lock(&inode->i_mutex); 2189 mutex_lock(&inode->i_mutex);
2192 ret = ntfs_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos); 2190 ret = ntfs_file_aio_write_nolock(iocb, iov, nr_segs, &iocb->ki_pos);
2193 mutex_unlock(&inode->i_mutex); 2191 mutex_unlock(&inode->i_mutex);
2194 if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { 2192 if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
2195 int err = sync_page_range(inode, mapping, pos, ret); 2193 int err = sync_page_range(inode, mapping, pos, ret);
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 2bbfa17090cf..d9ba0a931a03 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -961,25 +961,23 @@ static inline int ocfs2_write_should_remove_suid(struct inode *inode)
961} 961}
962 962
963static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, 963static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
964 const char __user *buf, 964 const struct iovec *iov,
965 size_t count, 965 unsigned long nr_segs,
966 loff_t pos) 966 loff_t pos)
967{ 967{
968 struct iovec local_iov = { .iov_base = (void __user *)buf,
969 .iov_len = count };
970 int ret, rw_level = -1, meta_level = -1, have_alloc_sem = 0; 968 int ret, rw_level = -1, meta_level = -1, have_alloc_sem = 0;
971 u32 clusters; 969 u32 clusters;
972 struct file *filp = iocb->ki_filp; 970 struct file *filp = iocb->ki_filp;
973 struct inode *inode = filp->f_dentry->d_inode; 971 struct inode *inode = filp->f_dentry->d_inode;
974 loff_t newsize, saved_pos; 972 loff_t newsize, saved_pos;
975 973
976 mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", filp, buf, 974 mlog_entry("(0x%p, %u, '%.*s')\n", filp,
977 (unsigned int)count, 975 (unsigned int)nr_segs,
978 filp->f_dentry->d_name.len, 976 filp->f_dentry->d_name.len,
979 filp->f_dentry->d_name.name); 977 filp->f_dentry->d_name.name);
980 978
981 /* happy write of zero bytes */ 979 /* happy write of zero bytes */
982 if (count == 0) 980 if (iocb->ki_left == 0)
983 return 0; 981 return 0;
984 982
985 if (!inode) { 983 if (!inode) {
@@ -1048,7 +1046,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
1048 } else { 1046 } else {
1049 saved_pos = iocb->ki_pos; 1047 saved_pos = iocb->ki_pos;
1050 } 1048 }
1051 newsize = count + saved_pos; 1049 newsize = iocb->ki_left + saved_pos;
1052 1050
1053 mlog(0, "pos=%lld newsize=%lld cursize=%lld\n", 1051 mlog(0, "pos=%lld newsize=%lld cursize=%lld\n",
1054 (long long) saved_pos, (long long) newsize, 1052 (long long) saved_pos, (long long) newsize,
@@ -1081,7 +1079,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
1081 if (!clusters) 1079 if (!clusters)
1082 break; 1080 break;
1083 1081
1084 ret = ocfs2_extend_file(inode, NULL, newsize, count); 1082 ret = ocfs2_extend_file(inode, NULL, newsize, iocb->ki_left);
1085 if (ret < 0) { 1083 if (ret < 0) {
1086 if (ret != -ENOSPC) 1084 if (ret != -ENOSPC)
1087 mlog_errno(ret); 1085 mlog_errno(ret);
@@ -1098,7 +1096,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
1098 /* communicate with ocfs2_dio_end_io */ 1096 /* communicate with ocfs2_dio_end_io */
1099 ocfs2_iocb_set_rw_locked(iocb); 1097 ocfs2_iocb_set_rw_locked(iocb);
1100 1098
1101 ret = generic_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos); 1099 ret = generic_file_aio_write_nolock(iocb, iov, nr_segs, iocb->ki_pos);
1102 1100
1103 /* buffered aio wouldn't have proper lock coverage today */ 1101 /* buffered aio wouldn't have proper lock coverage today */
1104 BUG_ON(ret == -EIOCBQUEUED && !(filp->f_flags & O_DIRECT)); 1102 BUG_ON(ret == -EIOCBQUEUED && !(filp->f_flags & O_DIRECT));
@@ -1132,16 +1130,16 @@ out:
1132} 1130}
1133 1131
1134static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, 1132static ssize_t ocfs2_file_aio_read(struct kiocb *iocb,
1135 char __user *buf, 1133 const struct iovec *iov,
1136 size_t count, 1134 unsigned long nr_segs,
1137 loff_t pos) 1135 loff_t pos)
1138{ 1136{
1139 int ret = 0, rw_level = -1, have_alloc_sem = 0; 1137 int ret = 0, rw_level = -1, have_alloc_sem = 0;
1140 struct file *filp = iocb->ki_filp; 1138 struct file *filp = iocb->ki_filp;
1141 struct inode *inode = filp->f_dentry->d_inode; 1139 struct inode *inode = filp->f_dentry->d_inode;
1142 1140
1143 mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", filp, buf, 1141 mlog_entry("(0x%p, %u, '%.*s')\n", filp,
1144 (unsigned int)count, 1142 (unsigned int)nr_segs,
1145 filp->f_dentry->d_name.len, 1143 filp->f_dentry->d_name.len,
1146 filp->f_dentry->d_name.name); 1144 filp->f_dentry->d_name.name);
1147 1145
@@ -1185,7 +1183,7 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb,
1185 } 1183 }
1186 ocfs2_meta_unlock(inode, 0); 1184 ocfs2_meta_unlock(inode, 0);
1187 1185
1188 ret = generic_file_aio_read(iocb, buf, count, iocb->ki_pos); 1186 ret = generic_file_aio_read(iocb, iov, nr_segs, iocb->ki_pos);
1189 if (ret == -EINVAL) 1187 if (ret == -EINVAL)
1190 mlog(ML_ERROR, "generic_file_aio_read returned -EINVAL\n"); 1188 mlog(ML_ERROR, "generic_file_aio_read returned -EINVAL\n");
1191 1189
diff --git a/fs/read_write.c b/fs/read_write.c
index d4cb3183c99c..679dd535380f 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -227,14 +227,20 @@ static void wait_on_retry_sync_kiocb(struct kiocb *iocb)
227 227
228ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos) 228ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
229{ 229{
230 struct iovec iov = { .iov_base = buf, .iov_len = len };
230 struct kiocb kiocb; 231 struct kiocb kiocb;
231 ssize_t ret; 232 ssize_t ret;
232 233
233 init_sync_kiocb(&kiocb, filp); 234 init_sync_kiocb(&kiocb, filp);
234 kiocb.ki_pos = *ppos; 235 kiocb.ki_pos = *ppos;
235 while (-EIOCBRETRY == 236 kiocb.ki_left = len;
236 (ret = filp->f_op->aio_read(&kiocb, buf, len, kiocb.ki_pos))) 237
238 for (;;) {
239 ret = filp->f_op->aio_read(&kiocb, &iov, 1, kiocb.ki_pos);
240 if (ret != -EIOCBRETRY)
241 break;
237 wait_on_retry_sync_kiocb(&kiocb); 242 wait_on_retry_sync_kiocb(&kiocb);
243 }
238 244
239 if (-EIOCBQUEUED == ret) 245 if (-EIOCBQUEUED == ret)
240 ret = wait_on_sync_kiocb(&kiocb); 246 ret = wait_on_sync_kiocb(&kiocb);
@@ -279,14 +285,20 @@ EXPORT_SYMBOL(vfs_read);
279 285
280ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) 286ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
281{ 287{
288 struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len };
282 struct kiocb kiocb; 289 struct kiocb kiocb;
283 ssize_t ret; 290 ssize_t ret;
284 291
285 init_sync_kiocb(&kiocb, filp); 292 init_sync_kiocb(&kiocb, filp);
286 kiocb.ki_pos = *ppos; 293 kiocb.ki_pos = *ppos;
287 while (-EIOCBRETRY == 294 kiocb.ki_left = len;
288 (ret = filp->f_op->aio_write(&kiocb, buf, len, kiocb.ki_pos))) 295
296 for (;;) {
297 ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos);
298 if (ret != -EIOCBRETRY)
299 break;
289 wait_on_retry_sync_kiocb(&kiocb); 300 wait_on_retry_sync_kiocb(&kiocb);
301 }
290 302
291 if (-EIOCBQUEUED == ret) 303 if (-EIOCBQUEUED == ret)
292 ret = wait_on_sync_kiocb(&kiocb); 304 ret = wait_on_sync_kiocb(&kiocb);
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index c11f6118c9ca..41f24369e47a 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -1334,7 +1334,7 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t
1334 if (err) 1334 if (err)
1335 return err; 1335 return err;
1336 } 1336 }
1337 result = generic_file_write(file, buf, count, ppos); 1337 result = do_sync_write(file, buf, count, ppos);
1338 1338
1339 if (after_file_end) { /* Now update i_size and remove the savelink */ 1339 if (after_file_end) { /* Now update i_size and remove the savelink */
1340 struct reiserfs_transaction_handle th; 1340 struct reiserfs_transaction_handle th;
@@ -1566,7 +1566,7 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t
1566} 1566}
1567 1567
1568const struct file_operations reiserfs_file_operations = { 1568const struct file_operations reiserfs_file_operations = {
1569 .read = generic_file_read, 1569 .read = do_sync_read,
1570 .write = reiserfs_file_write, 1570 .write = reiserfs_file_write,
1571 .ioctl = reiserfs_ioctl, 1571 .ioctl = reiserfs_ioctl,
1572#ifdef CONFIG_COMPAT 1572#ifdef CONFIG_COMPAT
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 41cfcba7ce49..4737971c6a39 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -49,50 +49,49 @@ static struct vm_operations_struct xfs_dmapi_file_vm_ops;
49STATIC inline ssize_t 49STATIC inline ssize_t
50__xfs_file_read( 50__xfs_file_read(
51 struct kiocb *iocb, 51 struct kiocb *iocb,
52 char __user *buf, 52 const struct iovec *iov,
53 unsigned long nr_segs,
53 int ioflags, 54 int ioflags,
54 size_t count,
55 loff_t pos) 55 loff_t pos)
56{ 56{
57 struct iovec iov = {buf, count};
58 struct file *file = iocb->ki_filp; 57 struct file *file = iocb->ki_filp;
59 bhv_vnode_t *vp = vn_from_inode(file->f_dentry->d_inode); 58 bhv_vnode_t *vp = vn_from_inode(file->f_dentry->d_inode);
60 59
61 BUG_ON(iocb->ki_pos != pos); 60 BUG_ON(iocb->ki_pos != pos);
62 if (unlikely(file->f_flags & O_DIRECT)) 61 if (unlikely(file->f_flags & O_DIRECT))
63 ioflags |= IO_ISDIRECT; 62 ioflags |= IO_ISDIRECT;
64 return bhv_vop_read(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL); 63 return bhv_vop_read(vp, iocb, iov, nr_segs, &iocb->ki_pos,
64 ioflags, NULL);
65} 65}
66 66
67STATIC ssize_t 67STATIC ssize_t
68xfs_file_aio_read( 68xfs_file_aio_read(
69 struct kiocb *iocb, 69 struct kiocb *iocb,
70 char __user *buf, 70 const struct iovec *iov,
71 size_t count, 71 unsigned long nr_segs,
72 loff_t pos) 72 loff_t pos)
73{ 73{
74 return __xfs_file_read(iocb, buf, IO_ISAIO, count, pos); 74 return __xfs_file_read(iocb, iov, nr_segs, IO_ISAIO, pos);
75} 75}
76 76
77STATIC ssize_t 77STATIC ssize_t
78xfs_file_aio_read_invis( 78xfs_file_aio_read_invis(
79 struct kiocb *iocb, 79 struct kiocb *iocb,
80 char __user *buf, 80 const struct iovec *iov,
81 size_t count, 81 unsigned long nr_segs,
82 loff_t pos) 82 loff_t pos)
83{ 83{
84 return __xfs_file_read(iocb, buf, IO_ISAIO|IO_INVIS, count, pos); 84 return __xfs_file_read(iocb, iov, nr_segs, IO_ISAIO|IO_INVIS, pos);
85} 85}
86 86
87STATIC inline ssize_t 87STATIC inline ssize_t
88__xfs_file_write( 88__xfs_file_write(
89 struct kiocb *iocb, 89 struct kiocb *iocb,
90 const char __user *buf, 90 const struct iovec *iov,
91 int ioflags, 91 unsigned long nr_segs,
92 size_t count, 92 int ioflags,
93 loff_t pos) 93 loff_t pos)
94{ 94{
95 struct iovec iov = {(void __user *)buf, count};
96 struct file *file = iocb->ki_filp; 95 struct file *file = iocb->ki_filp;
97 struct inode *inode = file->f_mapping->host; 96 struct inode *inode = file->f_mapping->host;
98 bhv_vnode_t *vp = vn_from_inode(inode); 97 bhv_vnode_t *vp = vn_from_inode(inode);
@@ -100,27 +99,28 @@ __xfs_file_write(
100 BUG_ON(iocb->ki_pos != pos); 99 BUG_ON(iocb->ki_pos != pos);
101 if (unlikely(file->f_flags & O_DIRECT)) 100 if (unlikely(file->f_flags & O_DIRECT))
102 ioflags |= IO_ISDIRECT; 101 ioflags |= IO_ISDIRECT;
103 return bhv_vop_write(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL); 102 return bhv_vop_write(vp, iocb, iov, nr_segs, &iocb->ki_pos,
103 ioflags, NULL);
104} 104}
105 105
106STATIC ssize_t 106STATIC ssize_t
107xfs_file_aio_write( 107xfs_file_aio_write(
108 struct kiocb *iocb, 108 struct kiocb *iocb,
109 const char __user *buf, 109 const struct iovec *iov,
110 size_t count, 110 unsigned long nr_segs,
111 loff_t pos) 111 loff_t pos)
112{ 112{
113 return __xfs_file_write(iocb, buf, IO_ISAIO, count, pos); 113 return __xfs_file_write(iocb, iov, nr_segs, IO_ISAIO, pos);
114} 114}
115 115
116STATIC ssize_t 116STATIC ssize_t
117xfs_file_aio_write_invis( 117xfs_file_aio_write_invis(
118 struct kiocb *iocb, 118 struct kiocb *iocb,
119 const char __user *buf, 119 const struct iovec *iov,
120 size_t count, 120 unsigned long nr_segs,
121 loff_t pos) 121 loff_t pos)
122{ 122{
123 return __xfs_file_write(iocb, buf, IO_ISAIO|IO_INVIS, count, pos); 123 return __xfs_file_write(iocb, iov, nr_segs, IO_ISAIO|IO_INVIS, pos);
124} 124}
125 125
126STATIC inline ssize_t 126STATIC inline ssize_t