aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorBadari Pulavarty <pbadari@us.ibm.com>2006-10-01 02:28:47 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-01 03:39:28 -0400
commitee0b3e671baff681d69fbf0db33b47603c0a8280 (patch)
tree3202ff815b2196c6c353bc5b28d7a2800df273ec /fs
parent027445c37282bc1ed26add45e573ad2d3e4860a5 (diff)
[PATCH] Remove readv/writev methods and use aio_read/aio_write instead
This patch removes readv() and writev() methods and replaces them with aio_read()/aio_write() methods. Signed-off-by: Badari Pulavarty <pbadari@us.ibm.com> Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/bad_inode.c2
-rw-r--r--fs/block_dev.c2
-rw-r--r--fs/cifs/cifsfs.c16
-rw-r--r--fs/compat.c44
-rw-r--r--fs/ext2/file.c2
-rw-r--r--fs/ext3/file.c2
-rw-r--r--fs/fat/file.c2
-rw-r--r--fs/fuse/dev.c37
-rw-r--r--fs/hostfs/hostfs_kern.c2
-rw-r--r--fs/jfs/file.c2
-rw-r--r--fs/ntfs/file.c2
-rw-r--r--fs/pipe.c59
-rw-r--r--fs/read_write.c101
-rw-r--r--fs/read_write.h14
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c94
15 files changed, 124 insertions, 257 deletions
diff --git a/fs/bad_inode.c b/fs/bad_inode.c
index 80599ae3396..34e6d7b220c 100644
--- a/fs/bad_inode.c
+++ b/fs/bad_inode.c
@@ -40,8 +40,6 @@ static const struct file_operations bad_file_ops =
40 .aio_fsync = EIO_ERROR, 40 .aio_fsync = EIO_ERROR,
41 .fasync = EIO_ERROR, 41 .fasync = EIO_ERROR,
42 .lock = EIO_ERROR, 42 .lock = EIO_ERROR,
43 .readv = EIO_ERROR,
44 .writev = EIO_ERROR,
45 .sendfile = EIO_ERROR, 43 .sendfile = EIO_ERROR,
46 .sendpage = EIO_ERROR, 44 .sendpage = EIO_ERROR,
47 .get_unmapped_area = EIO_ERROR, 45 .get_unmapped_area = EIO_ERROR,
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 8c819117310..0f143094ef1 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1191,8 +1191,6 @@ const struct file_operations def_blk_fops = {
1191#ifdef CONFIG_COMPAT 1191#ifdef CONFIG_COMPAT
1192 .compat_ioctl = compat_blkdev_ioctl, 1192 .compat_ioctl = compat_blkdev_ioctl,
1193#endif 1193#endif
1194 .readv = generic_file_readv,
1195 .writev = generic_file_write_nolock,
1196 .sendfile = generic_file_sendfile, 1194 .sendfile = generic_file_sendfile,
1197 .splice_read = generic_file_splice_read, 1195 .splice_read = generic_file_splice_read,
1198 .splice_write = generic_file_splice_write, 1196 .splice_write = generic_file_splice_write,
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 5abb42a7c53..c00c654f2e1 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -480,18 +480,6 @@ cifs_get_sb(struct file_system_type *fs_type,
480 return simple_set_mnt(mnt, sb); 480 return simple_set_mnt(mnt, sb);
481} 481}
482 482
483static ssize_t cifs_file_writev(struct file *file, const struct iovec *iov,
484 unsigned long nr_segs, loff_t *ppos)
485{
486 struct inode *inode = file->f_dentry->d_inode;
487 ssize_t written;
488
489 written = generic_file_writev(file, iov, nr_segs, ppos);
490 if (!CIFS_I(inode)->clientCanCacheAll)
491 filemap_fdatawrite(inode->i_mapping);
492 return written;
493}
494
495static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, 483static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
496 unsigned long nr_segs, loff_t pos) 484 unsigned long nr_segs, loff_t pos)
497{ 485{
@@ -577,8 +565,6 @@ struct inode_operations cifs_symlink_inode_ops = {
577const struct file_operations cifs_file_ops = { 565const struct file_operations cifs_file_ops = {
578 .read = do_sync_read, 566 .read = do_sync_read,
579 .write = do_sync_write, 567 .write = do_sync_write,
580 .readv = generic_file_readv,
581 .writev = cifs_file_writev,
582 .aio_read = generic_file_aio_read, 568 .aio_read = generic_file_aio_read,
583 .aio_write = cifs_file_aio_write, 569 .aio_write = cifs_file_aio_write,
584 .open = cifs_open, 570 .open = cifs_open,
@@ -620,8 +606,6 @@ const struct file_operations cifs_file_direct_ops = {
620const struct file_operations cifs_file_nobrl_ops = { 606const struct file_operations cifs_file_nobrl_ops = {
621 .read = do_sync_read, 607 .read = do_sync_read,
622 .write = do_sync_write, 608 .write = do_sync_write,
623 .readv = generic_file_readv,
624 .writev = cifs_file_writev,
625 .aio_read = generic_file_aio_read, 609 .aio_read = generic_file_aio_read,
626 .aio_write = cifs_file_aio_write, 610 .aio_write = cifs_file_aio_write,
627 .open = cifs_open, 611 .open = cifs_open,
diff --git a/fs/compat.c b/fs/compat.c
index 122b4e3992b..6b90bf35f61 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -70,6 +70,8 @@ int compat_printk(const char *fmt, ...)
70 return ret; 70 return ret;
71} 71}
72 72
73#include "read_write.h"
74
73/* 75/*
74 * Not all architectures have sys_utime, so implement this in terms 76 * Not all architectures have sys_utime, so implement this in terms
75 * of sys_utimes. 77 * of sys_utimes.
@@ -1149,9 +1151,6 @@ static ssize_t compat_do_readv_writev(int type, struct file *file,
1149 const struct compat_iovec __user *uvector, 1151 const struct compat_iovec __user *uvector,
1150 unsigned long nr_segs, loff_t *pos) 1152 unsigned long nr_segs, loff_t *pos)
1151{ 1153{
1152 typedef ssize_t (*io_fn_t)(struct file *, char __user *, size_t, loff_t *);
1153 typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *);
1154
1155 compat_ssize_t tot_len; 1154 compat_ssize_t tot_len;
1156 struct iovec iovstack[UIO_FASTIOV]; 1155 struct iovec iovstack[UIO_FASTIOV];
1157 struct iovec *iov=iovstack, *vector; 1156 struct iovec *iov=iovstack, *vector;
@@ -1234,39 +1233,18 @@ static ssize_t compat_do_readv_writev(int type, struct file *file,
1234 fnv = NULL; 1233 fnv = NULL;
1235 if (type == READ) { 1234 if (type == READ) {
1236 fn = file->f_op->read; 1235 fn = file->f_op->read;
1237 fnv = file->f_op->readv; 1236 fnv = file->f_op->aio_read;
1238 } else { 1237 } else {
1239 fn = (io_fn_t)file->f_op->write; 1238 fn = (io_fn_t)file->f_op->write;
1240 fnv = file->f_op->writev; 1239 fnv = file->f_op->aio_write;
1241 }
1242 if (fnv) {
1243 ret = fnv(file, iov, nr_segs, pos);
1244 goto out;
1245 } 1240 }
1246 1241
1247 /* Do it by hand, with file-ops */ 1242 if (fnv)
1248 ret = 0; 1243 ret = do_sync_readv_writev(file, iov, nr_segs, tot_len,
1249 vector = iov; 1244 pos, fnv);
1250 while (nr_segs > 0) { 1245 else
1251 void __user * base; 1246 ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn);
1252 size_t len;
1253 ssize_t nr;
1254
1255 base = vector->iov_base;
1256 len = vector->iov_len;
1257 vector++;
1258 nr_segs--;
1259
1260 nr = fn(file, base, len, pos);
1261 1247
1262 if (nr < 0) {
1263 if (!ret) ret = nr;
1264 break;
1265 }
1266 ret += nr;
1267 if (nr != len)
1268 break;
1269 }
1270out: 1248out:
1271 if (iov != iovstack) 1249 if (iov != iovstack)
1272 kfree(iov); 1250 kfree(iov);
@@ -1294,7 +1272,7 @@ compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec, unsign
1294 goto out; 1272 goto out;
1295 1273
1296 ret = -EINVAL; 1274 ret = -EINVAL;
1297 if (!file->f_op || (!file->f_op->readv && !file->f_op->read)) 1275 if (!file->f_op || (!file->f_op->aio_read && !file->f_op->read))
1298 goto out; 1276 goto out;
1299 1277
1300 ret = compat_do_readv_writev(READ, file, vec, vlen, &file->f_pos); 1278 ret = compat_do_readv_writev(READ, file, vec, vlen, &file->f_pos);
@@ -1317,7 +1295,7 @@ compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec, unsig
1317 goto out; 1295 goto out;
1318 1296
1319 ret = -EINVAL; 1297 ret = -EINVAL;
1320 if (!file->f_op || (!file->f_op->writev && !file->f_op->write)) 1298 if (!file->f_op || (!file->f_op->aio_write && !file->f_op->write))
1321 goto out; 1299 goto out;
1322 1300
1323 ret = compat_do_readv_writev(WRITE, file, vec, vlen, &file->f_pos); 1301 ret = compat_do_readv_writev(WRITE, file, vec, vlen, &file->f_pos);
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index e8bbed9dd26..e893e2be9ed 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -53,8 +53,6 @@ const struct file_operations ext2_file_operations = {
53 .open = generic_file_open, 53 .open = generic_file_open,
54 .release = ext2_release_file, 54 .release = ext2_release_file,
55 .fsync = ext2_sync_file, 55 .fsync = ext2_sync_file,
56 .readv = generic_file_readv,
57 .writev = generic_file_writev,
58 .sendfile = generic_file_sendfile, 56 .sendfile = generic_file_sendfile,
59 .splice_read = generic_file_splice_read, 57 .splice_read = generic_file_splice_read,
60 .splice_write = generic_file_splice_write, 58 .splice_write = generic_file_splice_write,
diff --git a/fs/ext3/file.c b/fs/ext3/file.c
index 5c762457bc8..e96c388047e 100644
--- a/fs/ext3/file.c
+++ b/fs/ext3/file.c
@@ -112,8 +112,6 @@ const struct file_operations ext3_file_operations = {
112 .write = do_sync_write, 112 .write = do_sync_write,
113 .aio_read = generic_file_aio_read, 113 .aio_read = generic_file_aio_read,
114 .aio_write = ext3_file_write, 114 .aio_write = ext3_file_write,
115 .readv = generic_file_readv,
116 .writev = generic_file_writev,
117 .ioctl = ext3_ioctl, 115 .ioctl = ext3_ioctl,
118#ifdef CONFIG_COMPAT 116#ifdef CONFIG_COMPAT
119 .compat_ioctl = ext3_compat_ioctl, 117 .compat_ioctl = ext3_compat_ioctl,
diff --git a/fs/fat/file.c b/fs/fat/file.c
index d50fc47169c..f4b8f8b3fbd 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -127,8 +127,6 @@ const struct file_operations fat_file_operations = {
127 .llseek = generic_file_llseek, 127 .llseek = generic_file_llseek,
128 .read = do_sync_read, 128 .read = do_sync_read,
129 .write = do_sync_write, 129 .write = do_sync_write,
130 .readv = generic_file_readv,
131 .writev = generic_file_writev,
132 .aio_read = generic_file_aio_read, 130 .aio_read = generic_file_aio_read,
133 .aio_write = generic_file_aio_write, 131 .aio_write = generic_file_aio_write,
134 .mmap = generic_file_mmap, 132 .mmap = generic_file_mmap,
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 4fc557c40cc..66571eafbb1 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -680,14 +680,15 @@ static int fuse_read_interrupt(struct fuse_conn *fc, struct fuse_req *req,
680 * request_end(). Otherwise add it to the processing list, and set 680 * request_end(). Otherwise add it to the processing list, and set
681 * the 'sent' flag. 681 * the 'sent' flag.
682 */ 682 */
683static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov, 683static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov,
684 unsigned long nr_segs, loff_t *off) 684 unsigned long nr_segs, loff_t pos)
685{ 685{
686 int err; 686 int err;
687 struct fuse_req *req; 687 struct fuse_req *req;
688 struct fuse_in *in; 688 struct fuse_in *in;
689 struct fuse_copy_state cs; 689 struct fuse_copy_state cs;
690 unsigned reqsize; 690 unsigned reqsize;
691 struct file *file = iocb->ki_filp;
691 struct fuse_conn *fc = fuse_get_conn(file); 692 struct fuse_conn *fc = fuse_get_conn(file);
692 if (!fc) 693 if (!fc)
693 return -EPERM; 694 return -EPERM;
@@ -761,15 +762,6 @@ static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov,
761 return err; 762 return err;
762} 763}
763 764
764static ssize_t fuse_dev_read(struct file *file, char __user *buf,
765 size_t nbytes, loff_t *off)
766{
767 struct iovec iov;
768 iov.iov_len = nbytes;
769 iov.iov_base = buf;
770 return fuse_dev_readv(file, &iov, 1, off);
771}
772
773/* Look up request on processing list by unique ID */ 765/* Look up request on processing list by unique ID */
774static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique) 766static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique)
775{ 767{
@@ -814,15 +806,15 @@ static int copy_out_args(struct fuse_copy_state *cs, struct fuse_out *out,
814 * it from the list and copy the rest of the buffer to the request. 806 * it from the list and copy the rest of the buffer to the request.
815 * The request is finished by calling request_end() 807 * The request is finished by calling request_end()
816 */ 808 */
817static ssize_t fuse_dev_writev(struct file *file, const struct iovec *iov, 809static ssize_t fuse_dev_write(struct kiocb *iocb, const struct iovec *iov,
818 unsigned long nr_segs, loff_t *off) 810 unsigned long nr_segs, loff_t pos)
819{ 811{
820 int err; 812 int err;
821 unsigned nbytes = iov_length(iov, nr_segs); 813 unsigned nbytes = iov_length(iov, nr_segs);
822 struct fuse_req *req; 814 struct fuse_req *req;
823 struct fuse_out_header oh; 815 struct fuse_out_header oh;
824 struct fuse_copy_state cs; 816 struct fuse_copy_state cs;
825 struct fuse_conn *fc = fuse_get_conn(file); 817 struct fuse_conn *fc = fuse_get_conn(iocb->ki_filp);
826 if (!fc) 818 if (!fc)
827 return -EPERM; 819 return -EPERM;
828 820
@@ -898,15 +890,6 @@ static ssize_t fuse_dev_writev(struct file *file, const struct iovec *iov,
898 return err; 890 return err;
899} 891}
900 892
901static ssize_t fuse_dev_write(struct file *file, const char __user *buf,
902 size_t nbytes, loff_t *off)
903{
904 struct iovec iov;
905 iov.iov_len = nbytes;
906 iov.iov_base = (char __user *) buf;
907 return fuse_dev_writev(file, &iov, 1, off);
908}
909
910static unsigned fuse_dev_poll(struct file *file, poll_table *wait) 893static unsigned fuse_dev_poll(struct file *file, poll_table *wait)
911{ 894{
912 unsigned mask = POLLOUT | POLLWRNORM; 895 unsigned mask = POLLOUT | POLLWRNORM;
@@ -1041,10 +1024,10 @@ static int fuse_dev_fasync(int fd, struct file *file, int on)
1041const struct file_operations fuse_dev_operations = { 1024const struct file_operations fuse_dev_operations = {
1042 .owner = THIS_MODULE, 1025 .owner = THIS_MODULE,
1043 .llseek = no_llseek, 1026 .llseek = no_llseek,
1044 .read = fuse_dev_read, 1027 .read = do_sync_read,
1045 .readv = fuse_dev_readv, 1028 .aio_read = fuse_dev_read,
1046 .write = fuse_dev_write, 1029 .write = do_sync_write,
1047 .writev = fuse_dev_writev, 1030 .aio_write = fuse_dev_write,
1048 .poll = fuse_dev_poll, 1031 .poll = fuse_dev_poll,
1049 .release = fuse_dev_release, 1032 .release = fuse_dev_release,
1050 .fasync = fuse_dev_fasync, 1033 .fasync = fuse_dev_fasync,
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index 322e876c35e..4908c38a588 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -389,8 +389,6 @@ static const struct file_operations hostfs_file_fops = {
389 .sendfile = generic_file_sendfile, 389 .sendfile = generic_file_sendfile,
390 .aio_read = generic_file_aio_read, 390 .aio_read = generic_file_aio_read,
391 .aio_write = generic_file_aio_write, 391 .aio_write = generic_file_aio_write,
392 .readv = generic_file_readv,
393 .writev = generic_file_writev,
394 .write = generic_file_write, 392 .write = generic_file_write,
395 .mmap = generic_file_mmap, 393 .mmap = generic_file_mmap,
396 .open = hostfs_file_open, 394 .open = hostfs_file_open,
diff --git a/fs/jfs/file.c b/fs/jfs/file.c
index 1c9745be5ad..f535f2911c1 100644
--- a/fs/jfs/file.c
+++ b/fs/jfs/file.c
@@ -108,8 +108,6 @@ const struct file_operations jfs_file_operations = {
108 .aio_read = generic_file_aio_read, 108 .aio_read = generic_file_aio_read,
109 .aio_write = generic_file_aio_write, 109 .aio_write = generic_file_aio_write,
110 .mmap = generic_file_mmap, 110 .mmap = generic_file_mmap,
111 .readv = generic_file_readv,
112 .writev = generic_file_writev,
113 .sendfile = generic_file_sendfile, 111 .sendfile = generic_file_sendfile,
114 .fsync = jfs_fsync, 112 .fsync = jfs_fsync,
115 .release = jfs_release, 113 .release = jfs_release,
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index 0c46f5c86b7..2f9b5a0953f 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -2298,11 +2298,9 @@ const struct file_operations ntfs_file_ops = {
2298 .llseek = generic_file_llseek, /* Seek inside file. */ 2298 .llseek = generic_file_llseek, /* Seek inside file. */
2299 .read = generic_file_read, /* Read from file. */ 2299 .read = generic_file_read, /* Read from file. */
2300 .aio_read = generic_file_aio_read, /* Async read from file. */ 2300 .aio_read = generic_file_aio_read, /* Async read from file. */
2301 .readv = generic_file_readv, /* Read from file. */
2302#ifdef NTFS_RW 2301#ifdef NTFS_RW
2303 .write = ntfs_file_write, /* Write to file. */ 2302 .write = ntfs_file_write, /* Write to file. */
2304 .aio_write = ntfs_file_aio_write, /* Async write to file. */ 2303 .aio_write = ntfs_file_aio_write, /* Async write to file. */
2305 .writev = ntfs_file_writev, /* Write to file. */
2306 /*.release = ,*/ /* Last file is closed. See 2304 /*.release = ,*/ /* Last file is closed. See
2307 fs/ext2/file.c:: 2305 fs/ext2/file.c::
2308 ext2_release_file() for 2306 ext2_release_file() for
diff --git a/fs/pipe.c b/fs/pipe.c
index f3b6f71e9d0..2e60e1c8815 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -218,9 +218,10 @@ static struct pipe_buf_operations anon_pipe_buf_ops = {
218}; 218};
219 219
220static ssize_t 220static ssize_t
221pipe_readv(struct file *filp, const struct iovec *_iov, 221pipe_read(struct kiocb *iocb, const struct iovec *_iov,
222 unsigned long nr_segs, loff_t *ppos) 222 unsigned long nr_segs, loff_t pos)
223{ 223{
224 struct file *filp = iocb->ki_filp;
224 struct inode *inode = filp->f_dentry->d_inode; 225 struct inode *inode = filp->f_dentry->d_inode;
225 struct pipe_inode_info *pipe; 226 struct pipe_inode_info *pipe;
226 int do_wakeup; 227 int do_wakeup;
@@ -330,17 +331,10 @@ redo:
330} 331}
331 332
332static ssize_t 333static ssize_t
333pipe_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) 334pipe_write(struct kiocb *iocb, const struct iovec *_iov,
334{ 335 unsigned long nr_segs, loff_t ppos)
335 struct iovec iov = { .iov_base = buf, .iov_len = count };
336
337 return pipe_readv(filp, &iov, 1, ppos);
338}
339
340static ssize_t
341pipe_writev(struct file *filp, const struct iovec *_iov,
342 unsigned long nr_segs, loff_t *ppos)
343{ 336{
337 struct file *filp = iocb->ki_filp;
344 struct inode *inode = filp->f_dentry->d_inode; 338 struct inode *inode = filp->f_dentry->d_inode;
345 struct pipe_inode_info *pipe; 339 struct pipe_inode_info *pipe;
346 ssize_t ret; 340 ssize_t ret;
@@ -510,15 +504,6 @@ out:
510} 504}
511 505
512static ssize_t 506static ssize_t
513pipe_write(struct file *filp, const char __user *buf,
514 size_t count, loff_t *ppos)
515{
516 struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = count };
517
518 return pipe_writev(filp, &iov, 1, ppos);
519}
520
521static ssize_t
522bad_pipe_r(struct file *filp, char __user *buf, size_t count, loff_t *ppos) 507bad_pipe_r(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
523{ 508{
524 return -EBADF; 509 return -EBADF;
@@ -736,8 +721,8 @@ pipe_rdwr_open(struct inode *inode, struct file *filp)
736 */ 721 */
737const struct file_operations read_fifo_fops = { 722const struct file_operations read_fifo_fops = {
738 .llseek = no_llseek, 723 .llseek = no_llseek,
739 .read = pipe_read, 724 .read = do_sync_read,
740 .readv = pipe_readv, 725 .aio_read = pipe_read,
741 .write = bad_pipe_w, 726 .write = bad_pipe_w,
742 .poll = pipe_poll, 727 .poll = pipe_poll,
743 .ioctl = pipe_ioctl, 728 .ioctl = pipe_ioctl,
@@ -749,8 +734,8 @@ const struct file_operations read_fifo_fops = {
749const struct file_operations write_fifo_fops = { 734const struct file_operations write_fifo_fops = {
750 .llseek = no_llseek, 735 .llseek = no_llseek,
751 .read = bad_pipe_r, 736 .read = bad_pipe_r,
752 .write = pipe_write, 737 .write = do_sync_write,
753 .writev = pipe_writev, 738 .aio_write = pipe_write,
754 .poll = pipe_poll, 739 .poll = pipe_poll,
755 .ioctl = pipe_ioctl, 740 .ioctl = pipe_ioctl,
756 .open = pipe_write_open, 741 .open = pipe_write_open,
@@ -760,10 +745,10 @@ const struct file_operations write_fifo_fops = {
760 745
761const struct file_operations rdwr_fifo_fops = { 746const struct file_operations rdwr_fifo_fops = {
762 .llseek = no_llseek, 747 .llseek = no_llseek,
763 .read = pipe_read, 748 .read = do_sync_read,
764 .readv = pipe_readv, 749 .aio_read = pipe_read,
765 .write = pipe_write, 750 .write = do_sync_write,
766 .writev = pipe_writev, 751 .aio_write = pipe_write,
767 .poll = pipe_poll, 752 .poll = pipe_poll,
768 .ioctl = pipe_ioctl, 753 .ioctl = pipe_ioctl,
769 .open = pipe_rdwr_open, 754 .open = pipe_rdwr_open,
@@ -773,8 +758,8 @@ const struct file_operations rdwr_fifo_fops = {
773 758
774static struct file_operations read_pipe_fops = { 759static struct file_operations read_pipe_fops = {
775 .llseek = no_llseek, 760 .llseek = no_llseek,
776 .read = pipe_read, 761 .read = do_sync_read,
777 .readv = pipe_readv, 762 .aio_read = pipe_read,
778 .write = bad_pipe_w, 763 .write = bad_pipe_w,
779 .poll = pipe_poll, 764 .poll = pipe_poll,
780 .ioctl = pipe_ioctl, 765 .ioctl = pipe_ioctl,
@@ -786,8 +771,8 @@ static struct file_operations read_pipe_fops = {
786static struct file_operations write_pipe_fops = { 771static struct file_operations write_pipe_fops = {
787 .llseek = no_llseek, 772 .llseek = no_llseek,
788 .read = bad_pipe_r, 773 .read = bad_pipe_r,
789 .write = pipe_write, 774 .write = do_sync_write,
790 .writev = pipe_writev, 775 .aio_write = pipe_write,
791 .poll = pipe_poll, 776 .poll = pipe_poll,
792 .ioctl = pipe_ioctl, 777 .ioctl = pipe_ioctl,
793 .open = pipe_write_open, 778 .open = pipe_write_open,
@@ -797,10 +782,10 @@ static struct file_operations write_pipe_fops = {
797 782
798static struct file_operations rdwr_pipe_fops = { 783static struct file_operations rdwr_pipe_fops = {
799 .llseek = no_llseek, 784 .llseek = no_llseek,
800 .read = pipe_read, 785 .read = do_sync_read,
801 .readv = pipe_readv, 786 .aio_read = pipe_read,
802 .write = pipe_write, 787 .write = do_sync_write,
803 .writev = pipe_writev, 788 .aio_write = pipe_write,
804 .poll = pipe_poll, 789 .poll = pipe_poll,
805 .ioctl = pipe_ioctl, 790 .ioctl = pipe_ioctl,
806 .open = pipe_rdwr_open, 791 .open = pipe_rdwr_open,
diff --git a/fs/read_write.c b/fs/read_write.c
index 679dd535380..32d54cca9bd 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -15,6 +15,7 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/syscalls.h> 16#include <linux/syscalls.h>
17#include <linux/pagemap.h> 17#include <linux/pagemap.h>
18#include "read_write.h"
18 19
19#include <asm/uaccess.h> 20#include <asm/uaccess.h>
20#include <asm/unistd.h> 21#include <asm/unistd.h>
@@ -450,6 +451,62 @@ unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to)
450 451
451EXPORT_UNUSED_SYMBOL(iov_shorten); /* June 2006 */ 452EXPORT_UNUSED_SYMBOL(iov_shorten); /* June 2006 */
452 453
454ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov,
455 unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn)
456{
457 struct kiocb kiocb;
458 ssize_t ret;
459
460 init_sync_kiocb(&kiocb, filp);
461 kiocb.ki_pos = *ppos;
462 kiocb.ki_left = len;
463 kiocb.ki_nbytes = len;
464
465 for (;;) {
466 ret = fn(&kiocb, iov, nr_segs, kiocb.ki_pos);
467 if (ret != -EIOCBRETRY)
468 break;
469 wait_on_retry_sync_kiocb(&kiocb);
470 }
471
472 if (ret == -EIOCBQUEUED)
473 ret = wait_on_sync_kiocb(&kiocb);
474 *ppos = kiocb.ki_pos;
475 return ret;
476}
477
478/* Do it by hand, with file-ops */
479ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov,
480 unsigned long nr_segs, loff_t *ppos, io_fn_t fn)
481{
482 struct iovec *vector = iov;
483 ssize_t ret = 0;
484
485 while (nr_segs > 0) {
486 void __user *base;
487 size_t len;
488 ssize_t nr;
489
490 base = vector->iov_base;
491 len = vector->iov_len;
492 vector++;
493 nr_segs--;
494
495 nr = fn(filp, base, len, ppos);
496
497 if (nr < 0) {
498 if (!ret)
499 ret = nr;
500 break;
501 }
502 ret += nr;
503 if (nr != len)
504 break;
505 }
506
507 return ret;
508}
509
453/* A write operation does a read from user space and vice versa */ 510/* A write operation does a read from user space and vice versa */
454#define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ) 511#define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ)
455 512
@@ -457,12 +514,9 @@ static ssize_t do_readv_writev(int type, struct file *file,
457 const struct iovec __user * uvector, 514 const struct iovec __user * uvector,
458 unsigned long nr_segs, loff_t *pos) 515 unsigned long nr_segs, loff_t *pos)
459{ 516{
460 typedef ssize_t (*io_fn_t)(struct file *, char __user *, size_t, loff_t *);
461 typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *);
462
463 size_t tot_len; 517 size_t tot_len;
464 struct iovec iovstack[UIO_FASTIOV]; 518 struct iovec iovstack[UIO_FASTIOV];
465 struct iovec *iov=iovstack, *vector; 519 struct iovec *iov = iovstack;
466 ssize_t ret; 520 ssize_t ret;
467 int seg; 521 int seg;
468 io_fn_t fn; 522 io_fn_t fn;
@@ -532,39 +586,18 @@ static ssize_t do_readv_writev(int type, struct file *file,
532 fnv = NULL; 586 fnv = NULL;
533 if (type == READ) { 587 if (type == READ) {
534 fn = file->f_op->read; 588 fn = file->f_op->read;
535 fnv = file->f_op->readv; 589 fnv = file->f_op->aio_read;
536 } else { 590 } else {
537 fn = (io_fn_t)file->f_op->write; 591 fn = (io_fn_t)file->f_op->write;
538 fnv = file->f_op->writev; 592 fnv = file->f_op->aio_write;
539 }
540 if (fnv) {
541 ret = fnv(file, iov, nr_segs, pos);
542 goto out;
543 } 593 }
544 594
545 /* Do it by hand, with file-ops */ 595 if (fnv)
546 ret = 0; 596 ret = do_sync_readv_writev(file, iov, nr_segs, tot_len,
547 vector = iov; 597 pos, fnv);
548 while (nr_segs > 0) { 598 else
549 void __user * base; 599 ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn);
550 size_t len;
551 ssize_t nr;
552
553 base = vector->iov_base;
554 len = vector->iov_len;
555 vector++;
556 nr_segs--;
557
558 nr = fn(file, base, len, pos);
559 600
560 if (nr < 0) {
561 if (!ret) ret = nr;
562 break;
563 }
564 ret += nr;
565 if (nr != len)
566 break;
567 }
568out: 601out:
569 if (iov != iovstack) 602 if (iov != iovstack)
570 kfree(iov); 603 kfree(iov);
@@ -585,7 +618,7 @@ ssize_t vfs_readv(struct file *file, const struct iovec __user *vec,
585{ 618{
586 if (!(file->f_mode & FMODE_READ)) 619 if (!(file->f_mode & FMODE_READ))
587 return -EBADF; 620 return -EBADF;
588 if (!file->f_op || (!file->f_op->readv && !file->f_op->read)) 621 if (!file->f_op || (!file->f_op->aio_read && !file->f_op->read))
589 return -EINVAL; 622 return -EINVAL;
590 623
591 return do_readv_writev(READ, file, vec, vlen, pos); 624 return do_readv_writev(READ, file, vec, vlen, pos);
@@ -598,7 +631,7 @@ ssize_t vfs_writev(struct file *file, const struct iovec __user *vec,
598{ 631{
599 if (!(file->f_mode & FMODE_WRITE)) 632 if (!(file->f_mode & FMODE_WRITE))
600 return -EBADF; 633 return -EBADF;
601 if (!file->f_op || (!file->f_op->writev && !file->f_op->write)) 634 if (!file->f_op || (!file->f_op->aio_write && !file->f_op->write))
602 return -EINVAL; 635 return -EINVAL;
603 636
604 return do_readv_writev(WRITE, file, vec, vlen, pos); 637 return do_readv_writev(WRITE, file, vec, vlen, pos);
diff --git a/fs/read_write.h b/fs/read_write.h
new file mode 100644
index 00000000000..d07b954c6e0
--- /dev/null
+++ b/fs/read_write.h
@@ -0,0 +1,14 @@
1/*
2 * This file is only for sharing some helpers from read_write.c with compat.c.
3 * Don't use anywhere else.
4 */
5
6
7typedef ssize_t (*io_fn_t)(struct file *, char __user *, size_t, loff_t *);
8typedef ssize_t (*iov_fn_t)(struct kiocb *, const struct iovec *,
9 unsigned long, loff_t);
10
11ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov,
12 unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn);
13ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov,
14 unsigned long nr_segs, loff_t *ppos, io_fn_t fn);
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 4737971c6a3..d93d8dd1958 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -123,96 +123,6 @@ xfs_file_aio_write_invis(
123 return __xfs_file_write(iocb, iov, nr_segs, IO_ISAIO|IO_INVIS, pos); 123 return __xfs_file_write(iocb, iov, nr_segs, IO_ISAIO|IO_INVIS, pos);
124} 124}
125 125
126STATIC inline ssize_t
127__xfs_file_readv(
128 struct file *file,
129 const struct iovec *iov,
130 int ioflags,
131 unsigned long nr_segs,
132 loff_t *ppos)
133{
134 struct inode *inode = file->f_mapping->host;
135 bhv_vnode_t *vp = vn_from_inode(inode);
136 struct kiocb kiocb;
137 ssize_t rval;
138
139 init_sync_kiocb(&kiocb, file);
140 kiocb.ki_pos = *ppos;
141
142 if (unlikely(file->f_flags & O_DIRECT))
143 ioflags |= IO_ISDIRECT;
144 rval = bhv_vop_read(vp, &kiocb, iov, nr_segs,
145 &kiocb.ki_pos, ioflags, NULL);
146
147 *ppos = kiocb.ki_pos;
148 return rval;
149}
150
151STATIC ssize_t
152xfs_file_readv(
153 struct file *file,
154 const struct iovec *iov,
155 unsigned long nr_segs,
156 loff_t *ppos)
157{
158 return __xfs_file_readv(file, iov, 0, nr_segs, ppos);
159}
160
161STATIC ssize_t
162xfs_file_readv_invis(
163 struct file *file,
164 const struct iovec *iov,
165 unsigned long nr_segs,
166 loff_t *ppos)
167{
168 return __xfs_file_readv(file, iov, IO_INVIS, nr_segs, ppos);
169}
170
171STATIC inline ssize_t
172__xfs_file_writev(
173 struct file *file,
174 const struct iovec *iov,
175 int ioflags,
176 unsigned long nr_segs,
177 loff_t *ppos)
178{
179 struct inode *inode = file->f_mapping->host;
180 bhv_vnode_t *vp = vn_from_inode(inode);
181 struct kiocb kiocb;
182 ssize_t rval;
183
184 init_sync_kiocb(&kiocb, file);
185 kiocb.ki_pos = *ppos;
186 if (unlikely(file->f_flags & O_DIRECT))
187 ioflags |= IO_ISDIRECT;
188
189 rval = bhv_vop_write(vp, &kiocb, iov, nr_segs,
190 &kiocb.ki_pos, ioflags, NULL);
191
192 *ppos = kiocb.ki_pos;
193 return rval;
194}
195
196STATIC ssize_t
197xfs_file_writev(
198 struct file *file,
199 const struct iovec *iov,
200 unsigned long nr_segs,
201 loff_t *ppos)
202{
203 return __xfs_file_writev(file, iov, 0, nr_segs, ppos);
204}
205
206STATIC ssize_t
207xfs_file_writev_invis(
208 struct file *file,
209 const struct iovec *iov,
210 unsigned long nr_segs,
211 loff_t *ppos)
212{
213 return __xfs_file_writev(file, iov, IO_INVIS, nr_segs, ppos);
214}
215
216STATIC ssize_t 126STATIC ssize_t
217xfs_file_sendfile( 127xfs_file_sendfile(
218 struct file *filp, 128 struct file *filp,
@@ -540,8 +450,6 @@ const struct file_operations xfs_file_operations = {
540 .llseek = generic_file_llseek, 450 .llseek = generic_file_llseek,
541 .read = do_sync_read, 451 .read = do_sync_read,
542 .write = do_sync_write, 452 .write = do_sync_write,
543 .readv = xfs_file_readv,
544 .writev = xfs_file_writev,
545 .aio_read = xfs_file_aio_read, 453 .aio_read = xfs_file_aio_read,
546 .aio_write = xfs_file_aio_write, 454 .aio_write = xfs_file_aio_write,
547 .sendfile = xfs_file_sendfile, 455 .sendfile = xfs_file_sendfile,
@@ -565,8 +473,6 @@ const struct file_operations xfs_invis_file_operations = {
565 .llseek = generic_file_llseek, 473 .llseek = generic_file_llseek,
566 .read = do_sync_read, 474 .read = do_sync_read,
567 .write = do_sync_write, 475 .write = do_sync_write,
568 .readv = xfs_file_readv_invis,
569 .writev = xfs_file_writev_invis,
570 .aio_read = xfs_file_aio_read_invis, 476 .aio_read = xfs_file_aio_read_invis,
571 .aio_write = xfs_file_aio_write_invis, 477 .aio_write = xfs_file_aio_write_invis,
572 .sendfile = xfs_file_sendfile_invis, 478 .sendfile = xfs_file_sendfile_invis,