Merge branch 'for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 15 Apr 2015 20:22:56 +0000 (13:22 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 15 Apr 2015 20:22:56 +0000 (13:22 -0700)
Pull second vfs update from Al Viro:
 "Now that net-next went in...  Here's the next big chunk - killing
  ->aio_read() and ->aio_write().

  There'll be one more pile today (direct_IO changes and
  generic_write_checks() cleanups/fixes), but I'd prefer to keep that
  one separate"

* 'for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (37 commits)
  ->aio_read and ->aio_write removed
  pcm: another weird API abuse
  infinibad: weird APIs switched to ->write_iter()
  kill do_sync_read/do_sync_write
  fuse: use iov_iter_get_pages() for non-splice path
  fuse: switch to ->read_iter/->write_iter
  switch drivers/char/mem.c to ->read_iter/->write_iter
  make new_sync_{read,write}() static
  coredump: accept any write method
  switch /dev/loop to vfs_iter_write()
  serial2002: switch to __vfs_read/__vfs_write
  ashmem: use __vfs_read()
  export __vfs_read()
  autofs: switch to __vfs_write()
  new helper: __vfs_write()
  switch hugetlbfs to ->read_iter()
  coda: switch to ->read_iter/->write_iter
  ncpfs: switch to ->read_iter/->write_iter
  net/9p: remove (now-)unused helpers
  p9_client_attach(): set fid->uid correctly
  ...

90 files changed:
Documentation/filesystems/Locking
Documentation/filesystems/porting
Documentation/filesystems/vfs.txt
arch/s390/hypfs/inode.c
drivers/block/loop.c
drivers/char/mem.c
drivers/char/raw.c
drivers/infiniband/hw/ipath/ipath_file_ops.c
drivers/infiniband/hw/qib/qib_file_ops.c
drivers/net/macvtap.c
drivers/net/tun.c
drivers/staging/android/ashmem.c
drivers/staging/comedi/drivers/serial2002.c
drivers/staging/lustre/lustre/llite/file.c
drivers/staging/lustre/lustre/llite/llite_internal.h
drivers/usb/gadget/function/f_fs.c
drivers/usb/gadget/legacy/inode.c
fs/9p/v9fs_vfs.h
fs/9p/vfs_addr.c
fs/9p/vfs_dir.c
fs/9p/vfs_file.c
fs/9p/xattr.c
fs/adfs/file.c
fs/affs/file.c
fs/afs/file.c
fs/aio.c
fs/autofs4/autofs_i.h
fs/autofs4/waitq.c
fs/bfs/file.c
fs/block_dev.c
fs/btrfs/file.c
fs/ceph/file.c
fs/cifs/cifsfs.c
fs/coda/file.c
fs/coredump.c
fs/ecryptfs/file.c
fs/exofs/file.c
fs/ext2/file.c
fs/ext3/file.c
fs/ext4/file.c
fs/f2fs/file.c
fs/fat/file.c
fs/file_table.c
fs/fuse/cuse.c
fs/fuse/dev.c
fs/fuse/file.c
fs/gfs2/file.c
fs/hfs/inode.c
fs/hfsplus/inode.c
fs/hostfs/hostfs_kern.c
fs/hpfs/file.c
fs/hugetlbfs/inode.c
fs/jffs2/file.c
fs/jfs/file.c
fs/logfs/file.c
fs/minix/file.c
fs/ncpfs/file.c
fs/ncpfs/ncplib_kernel.c
fs/ncpfs/ncplib_kernel.h
fs/nfs/file.c
fs/nfs/nfs4file.c
fs/nilfs2/file.c
fs/ntfs/file.c
fs/ocfs2/file.c
fs/omfs/file.c
fs/open.c
fs/pipe.c
fs/ramfs/file-mmu.c
fs/ramfs/file-nommu.c
fs/read_write.c
fs/reiserfs/file.c
fs/romfs/mmap-nommu.c
fs/sysv/file.c
fs/ubifs/file.c
fs/udf/file.c
fs/ufs/file.c
fs/xfs/xfs_file.c
include/linux/fs.h
include/net/9p/client.h
include/net/9p/transport.h
kernel/acct.c
mm/nommu.c
mm/shmem.c
net/9p/client.c
net/9p/protocol.c
net/9p/trans_common.c
net/9p/trans_common.h
net/9p/trans_virtio.c
net/socket.c
sound/core/pcm_native.c

index f91926f2f4824dee2c6785dcaf4cedd84df838e9..c3cd6279e92e7a934ce799a8ca942c42872b4815 100644 (file)
@@ -429,8 +429,6 @@ prototypes:
        loff_t (*llseek) (struct file *, loff_t, int);
        ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
        ssize_t (*write) (struct file *, 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);
        ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
        ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
        int (*iterate) (struct file *, struct dir_context *);
index fa2db081505e6d6d581ea4ee6d8f1eaab56a3482..e69274de8d0c9c1754cc40b8d99d78a724e63e50 100644 (file)
@@ -471,3 +471,15 @@ in your dentry operations instead.
 [mandatory]
        f_dentry is gone; use f_path.dentry, or, better yet, see if you can avoid
        it entirely.
+--
+[mandatory]
+       never call ->read() and ->write() directly; use __vfs_{read,write} or
+       wrappers; instead of checking for ->write or ->read being NULL, look for
+       FMODE_CAN_{WRITE,READ} in file->f_mode.
+--
+[mandatory]
+       do _not_ use new_sync_{read,write} for ->read/->write; leave it NULL
+       instead.
+--
+[mandatory]
+       ->aio_read/->aio_write are gone.  Use ->read_iter/->write_iter.
index 966b22829f3b605b92f19ce43665225ab17a8a7e..207cdca68bedf118554bd0addf5517546c190e17 100644 (file)
@@ -804,8 +804,6 @@ struct file_operations {
        loff_t (*llseek) (struct file *, loff_t, int);
        ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
        ssize_t (*write) (struct file *, 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);
        ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
        ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
        int (*iterate) (struct file *, struct dir_context *);
@@ -838,14 +836,10 @@ otherwise noted.
 
   read: called by read(2) and related system calls
 
-  aio_read: vectored, possibly asynchronous read
-
   read_iter: possibly asynchronous read with iov_iter as destination
 
   write: called by write(2) and related system calls
 
-  aio_write: vectored, possibly asynchronous write
-
   write_iter: possibly asynchronous write with iov_iter as source
 
   iterate: called when the VFS needs to read the directory contents
index df7d8cbee377a229c5f609d92ea7b72045c9cc86..3f5c799b7fb53aecc3af6cf8b877705cb0e8bd0e 100644 (file)
@@ -437,8 +437,6 @@ struct dentry *hypfs_create_str(struct dentry *dir,
 static const struct file_operations hypfs_file_ops = {
        .open           = hypfs_open,
        .release        = hypfs_release,
-       .read           = new_sync_read,
-       .write          = new_sync_write,
        .read_iter      = hypfs_read_iter,
        .write_iter     = hypfs_write_iter,
        .llseek         = no_llseek,
index d1f168b73634321dadb6c57571c0cd8a9de8304b..c4fd1e45ce1e82a8f303aacda953539dba99b3be 100644 (file)
@@ -75,6 +75,7 @@
 #include <linux/sysfs.h>
 #include <linux/miscdevice.h>
 #include <linux/falloc.h>
+#include <linux/uio.h>
 #include "loop.h"
 
 #include <asm/uaccess.h>
@@ -229,13 +230,14 @@ lo_do_transfer(struct loop_device *lo, int cmd,
 static int __do_lo_send_write(struct file *file,
                u8 *buf, const int len, loff_t pos)
 {
+       struct kvec kvec = {.iov_base = buf, .iov_len = len};
+       struct iov_iter from;
        ssize_t bw;
-       mm_segment_t old_fs = get_fs();
+
+       iov_iter_kvec(&from, ITER_KVEC | WRITE, &kvec, 1, len);
 
        file_start_write(file);
-       set_fs(get_ds());
-       bw = file->f_op->write(file, buf, len, &pos);
-       set_fs(old_fs);
+       bw = vfs_iter_write(file, &from, &pos);
        file_end_write(file);
        if (likely(bw == len))
                return 0;
@@ -767,7 +769,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
                goto out_putf;
 
        if (!(file->f_mode & FMODE_WRITE) || !(mode & FMODE_WRITE) ||
-           !file->f_op->write)
+           !file->f_op->write_iter)
                lo_flags |= LO_FLAGS_READ_ONLY;
 
        lo_blocksize = S_ISBLK(inode->i_mode) ?
index 9c4fd7a8e2e5c466e6df5144082a22b868214d9f..6b1721f978c2945f4af716636c8373fe8807dca0 100644 (file)
@@ -607,16 +607,16 @@ static ssize_t write_null(struct file *file, const char __user *buf,
        return count;
 }
 
-static ssize_t aio_read_null(struct kiocb *iocb, const struct iovec *iov,
-                            unsigned long nr_segs, loff_t pos)
+static ssize_t read_iter_null(struct kiocb *iocb, struct iov_iter *to)
 {
        return 0;
 }
 
-static ssize_t aio_write_null(struct kiocb *iocb, const struct iovec *iov,
-                             unsigned long nr_segs, loff_t pos)
+static ssize_t write_iter_null(struct kiocb *iocb, struct iov_iter *from)
 {
-       return iov_length(iov, nr_segs);
+       size_t count = iov_iter_count(from);
+       iov_iter_advance(from, count);
+       return count;
 }
 
 static int pipe_to_null(struct pipe_inode_info *info, struct pipe_buffer *buf,
@@ -718,7 +718,7 @@ static int open_port(struct inode *inode, struct file *filp)
 #define zero_lseek     null_lseek
 #define full_lseek      null_lseek
 #define write_zero     write_null
-#define aio_write_zero aio_write_null
+#define write_iter_zero        write_iter_null
 #define open_mem       open_port
 #define open_kmem      open_mem
 
@@ -750,8 +750,8 @@ static const struct file_operations null_fops = {
        .llseek         = null_lseek,
        .read           = read_null,
        .write          = write_null,
-       .aio_read       = aio_read_null,
-       .aio_write      = aio_write_null,
+       .read_iter      = read_iter_null,
+       .write_iter     = write_iter_null,
        .splice_write   = splice_write_null,
 };
 
@@ -764,10 +764,9 @@ static const struct file_operations __maybe_unused port_fops = {
 
 static const struct file_operations zero_fops = {
        .llseek         = zero_lseek,
-       .read           = new_sync_read,
        .write          = write_zero,
        .read_iter      = read_iter_zero,
-       .aio_write      = aio_write_zero,
+       .write_iter     = write_iter_zero,
        .mmap           = mmap_zero,
 #ifndef CONFIG_MMU
        .mmap_capabilities = zero_mmap_capabilities,
@@ -776,7 +775,6 @@ static const struct file_operations zero_fops = {
 
 static const struct file_operations full_fops = {
        .llseek         = full_lseek,
-       .read           = new_sync_read,
        .read_iter      = read_iter_zero,
        .write          = write_full,
 };
index 6e29bf2db5367732eaf68f05d1c75dd22adf7966..5fc291c6157e3121f57d0a30e8d52a5021e3253c 100644 (file)
@@ -282,9 +282,7 @@ static long raw_ctl_compat_ioctl(struct file *file, unsigned int cmd,
 #endif
 
 static const struct file_operations raw_fops = {
-       .read           = new_sync_read,
        .read_iter      = blkdev_read_iter,
-       .write          = new_sync_write,
        .write_iter     = blkdev_write_iter,
        .fsync          = blkdev_fsync,
        .open           = raw_open,
index aed8afee56da16a6a3609a247c9bea2c54060c44..450d1596500512c7f41174dec8d078bb15edb79a 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/io.h>
 #include <linux/jiffies.h>
 #include <linux/cpu.h>
+#include <linux/uio.h>
 #include <asm/pgtable.h>
 
 #include "ipath_kernel.h"
@@ -52,15 +53,19 @@ static int ipath_open(struct inode *, struct file *);
 static int ipath_close(struct inode *, struct file *);
 static ssize_t ipath_write(struct file *, const char __user *, size_t,
                           loff_t *);
-static ssize_t ipath_writev(struct kiocb *, const struct iovec *,
-                           unsigned long , loff_t);
+static ssize_t ipath_write_iter(struct kiocb *, struct iov_iter *from);
 static unsigned int ipath_poll(struct file *, struct poll_table_struct *);
 static int ipath_mmap(struct file *, struct vm_area_struct *);
 
+/*
+ * This is really, really weird shit - write() and writev() here
+ * have completely unrelated semantics.  Sucky userland ABI,
+ * film at 11.
+ */
 static const struct file_operations ipath_file_ops = {
        .owner = THIS_MODULE,
        .write = ipath_write,
-       .aio_write = ipath_writev,
+       .write_iter = ipath_write_iter,
        .open = ipath_open,
        .release = ipath_close,
        .poll = ipath_poll,
@@ -2413,18 +2418,17 @@ bail:
        return ret;
 }
 
-static ssize_t ipath_writev(struct kiocb *iocb, const struct iovec *iov,
-                           unsigned long dim, loff_t off)
+static ssize_t ipath_write_iter(struct kiocb *iocb, struct iov_iter *from)
 {
        struct file *filp = iocb->ki_filp;
        struct ipath_filedata *fp = filp->private_data;
        struct ipath_portdata *pd = port_fp(filp);
        struct ipath_user_sdma_queue *pq = fp->pq;
 
-       if (!dim)
+       if (!iter_is_iovec(from) || !from->nr_segs)
                return -EINVAL;
 
-       return ipath_user_sdma_writev(pd->port_dd, pq, iov, dim);
+       return ipath_user_sdma_writev(pd->port_dd, pq, from->iov, from->nr_segs);
 }
 
 static struct class *ipath_class;
index 14046f5a37fa332cf5e5b25ba1a86a5fe7918188..9ea6c440a00ca7012f6422f1ffd7f525b8d80548 100644 (file)
@@ -43,6 +43,7 @@
 #include <asm/pgtable.h>
 #include <linux/delay.h>
 #include <linux/export.h>
+#include <linux/uio.h>
 
 #include "qib.h"
 #include "qib_common.h"
 static int qib_open(struct inode *, struct file *);
 static int qib_close(struct inode *, struct file *);
 static ssize_t qib_write(struct file *, const char __user *, size_t, loff_t *);
-static ssize_t qib_aio_write(struct kiocb *, const struct iovec *,
-                            unsigned long, loff_t);
+static ssize_t qib_write_iter(struct kiocb *, struct iov_iter *);
 static unsigned int qib_poll(struct file *, struct poll_table_struct *);
 static int qib_mmapf(struct file *, struct vm_area_struct *);
 
+/*
+ * This is really, really weird shit - write() and writev() here
+ * have completely unrelated semantics.  Sucky userland ABI,
+ * film at 11.
+ */
 static const struct file_operations qib_file_ops = {
        .owner = THIS_MODULE,
        .write = qib_write,
-       .aio_write = qib_aio_write,
+       .write_iter = qib_write_iter,
        .open = qib_open,
        .release = qib_close,
        .poll = qib_poll,
@@ -2248,17 +2253,16 @@ bail:
        return ret;
 }
 
-static ssize_t qib_aio_write(struct kiocb *iocb, const struct iovec *iov,
-                            unsigned long dim, loff_t off)
+static ssize_t qib_write_iter(struct kiocb *iocb, struct iov_iter *from)
 {
        struct qib_filedata *fp = iocb->ki_filp->private_data;
        struct qib_ctxtdata *rcd = ctxt_fp(iocb->ki_filp);
        struct qib_user_sdma_queue *pq = fp->pq;
 
-       if (!dim || !pq)
+       if (!iter_is_iovec(from) || !from->nr_segs || !pq)
                return -EINVAL;
-
-       return qib_user_sdma_writev(rcd, pq, iov, dim);
+                        
+       return qib_user_sdma_writev(rcd, pq, from->iov, from->nr_segs);
 }
 
 static struct class *qib_class;
index 8362aef0c15e534241babfddbcd6cd6912ed1a8c..9c91ff8724851d5d284bd8c5b128f94d57e1537e 100644 (file)
@@ -1118,8 +1118,6 @@ static const struct file_operations macvtap_fops = {
        .owner          = THIS_MODULE,
        .open           = macvtap_open,
        .release        = macvtap_release,
-       .read           = new_sync_read,
-       .write          = new_sync_write,
        .read_iter      = macvtap_read_iter,
        .write_iter     = macvtap_write_iter,
        .poll           = macvtap_poll,
index b96b94cee76035cc6131d402f85d63ca2c0421e7..e470ae59d40536fe7530774cb473ebe57000f9a8 100644 (file)
@@ -2223,8 +2223,6 @@ static void tun_chr_show_fdinfo(struct seq_file *m, struct file *f)
 static const struct file_operations tun_fops = {
        .owner  = THIS_MODULE,
        .llseek = no_llseek,
-       .read  = new_sync_read,
-       .write = new_sync_write,
        .read_iter  = tun_chr_read_iter,
        .write_iter = tun_chr_write_iter,
        .poll   = tun_chr_poll,
index d140b733940cc3ffd8ea567bb286aa4ed50ac8f4..c5c037ccf32cc0097f25fe16ddc7848cbd41e547 100644 (file)
@@ -310,7 +310,7 @@ static ssize_t ashmem_read(struct file *file, char __user *buf,
         * be destroyed until all references to the file are dropped and
         * ashmem_release is called.
         */
-       ret = asma->file->f_op->read(asma->file, buf, len, pos);
+       ret = __vfs_read(asma->file, buf, len, pos);
        if (ret >= 0) {
                /** Update backing file pos, since f_ops->read() doesn't */
                asma->file->f_pos = *pos;
index ad35ed6e93f0a26554348922ee02f04e758f6f04..304ebff119eeac1cd83a70cd318b5957b2135f11 100644 (file)
@@ -108,24 +108,16 @@ static int serial2002_tty_write(struct file *f, unsigned char *buf, int count)
 {
        const char __user *p = (__force const char __user *)buf;
        int result;
+       loff_t offset = 0;
        mm_segment_t oldfs;
 
        oldfs = get_fs();
        set_fs(KERNEL_DS);
-       f->f_pos = 0;
-       result = f->f_op->write(f, p, count, &f->f_pos);
+       result = __vfs_write(f, p, count, &offset);
        set_fs(oldfs);
        return result;
 }
 
-static int serial2002_tty_readb(struct file *f, unsigned char *buf)
-{
-       char __user *p = (__force char __user *)buf;
-
-       f->f_pos = 0;
-       return f->f_op->read(f, p, 1, &f->f_pos);
-}
-
 static void serial2002_tty_read_poll_wait(struct file *f, int timeout)
 {
        struct poll_wqueues table;
@@ -161,13 +153,15 @@ static int serial2002_tty_read(struct file *f, int timeout)
        result = -1;
        if (!IS_ERR(f)) {
                mm_segment_t oldfs;
+               char __user *p = (__force char __user *)&ch;
+               loff_t offset = 0;
 
                oldfs = get_fs();
                set_fs(KERNEL_DS);
                if (f->f_op->poll) {
                        serial2002_tty_read_poll_wait(f, timeout);
 
-                       if (serial2002_tty_readb(f, &ch) == 1)
+                       if (__vfs_read(f, p, 1, &offset) == 1)
                                result = ch;
                } else {
                        /* Device does not support poll, busy wait */
@@ -178,7 +172,7 @@ static int serial2002_tty_read(struct file *f, int timeout)
                                if (retries >= timeout)
                                        break;
 
-                               if (serial2002_tty_readb(f, &ch) == 1) {
+                               if (__vfs_read(f, p, 1, &offset) == 1) {
                                        result = ch;
                                        break;
                                }
index 85e74d18d1c70bdeae1e639d6cd3b4ecdbd1782b..529062ea112b63ca99a604b7c0686b6d459d172a 100644 (file)
@@ -3135,9 +3135,7 @@ int ll_inode_permission(struct inode *inode, int mask)
 
 /* -o localflock - only provides locally consistent flock locks */
 struct file_operations ll_file_operations = {
-       .read      = new_sync_read,
        .read_iter = ll_file_read_iter,
-       .write    = new_sync_write,
        .write_iter = ll_file_write_iter,
        .unlocked_ioctl = ll_file_ioctl,
        .open      = ll_file_open,
@@ -3150,9 +3148,7 @@ struct file_operations ll_file_operations = {
 };
 
 struct file_operations ll_file_operations_flock = {
-       .read      = new_sync_read,
        .read_iter    = ll_file_read_iter,
-       .write    = new_sync_write,
        .write_iter   = ll_file_write_iter,
        .unlocked_ioctl = ll_file_ioctl,
        .open      = ll_file_open,
@@ -3168,9 +3164,7 @@ struct file_operations ll_file_operations_flock = {
 
 /* These are for -o noflock - to return ENOSYS on flock calls */
 struct file_operations ll_file_operations_noflock = {
-       .read      = new_sync_read,
        .read_iter    = ll_file_read_iter,
-       .write    = new_sync_write,
        .write_iter   = ll_file_write_iter,
        .unlocked_ioctl = ll_file_ioctl,
        .open      = ll_file_open,
index 2af1d7286250a32097ac89d1735e08ae3c97ebad..e7422f5c9c6f408deb97d93583a52fe30ebc20c9 100644 (file)
@@ -938,10 +938,8 @@ struct ll_cl_context {
 };
 
 struct vvp_thread_info {
-       struct iovec     vti_local_iov;
        struct vvp_io_args   vti_args;
        struct ra_io_arg     vti_ria;
-       struct kiocb     vti_kiocb;
        struct ll_cl_context vti_io_ctx;
 };
 
index a12315a78248d4a40349586062e043b8574d1308..6bdb5706904497ca9eccb7fd5d979c67824d8600 100644 (file)
@@ -1061,8 +1061,6 @@ static const struct file_operations ffs_epfile_operations = {
        .llseek =       no_llseek,
 
        .open =         ffs_epfile_open,
-       .write =        new_sync_write,
-       .read =         new_sync_read,
        .write_iter =   ffs_epfile_write_iter,
        .read_iter =    ffs_epfile_read_iter,
        .release =      ffs_epfile_release,
index 662ef2c1c62b67d0340cbf8593d515f14f2568dc..6af58c6dba5ebe7ea134197537864b95c8bfe002 100644 (file)
@@ -699,8 +699,6 @@ static const struct file_operations ep_io_operations = {
        .open =         ep_open,
        .release =      ep_release,
        .llseek =       no_llseek,
-       .read =         new_sync_read,
-       .write =        new_sync_write,
        .unlocked_ioctl = ep_ioctl,
        .read_iter =    ep_read_iter,
        .write_iter =   ep_write_iter,
index b83ebfbf3fdc7db1ab56b36cea1c89626b24e9cb..5a0db6dec8d1fd4ad2673a03188a910606ae42b3 100644 (file)
@@ -68,14 +68,10 @@ int v9fs_file_open(struct inode *inode, struct file *file);
 void v9fs_inode2stat(struct inode *inode, struct p9_wstat *stat);
 int v9fs_uflags2omode(int uflags, int extended);
 
-ssize_t v9fs_file_readn(struct file *, char *, char __user *, u32, u64);
-ssize_t v9fs_fid_readn(struct p9_fid *, char *, char __user *, u32, u64);
 void v9fs_blank_wstat(struct p9_wstat *wstat);
 int v9fs_vfs_setattr_dotl(struct dentry *, struct iattr *);
 int v9fs_file_fsync_dotl(struct file *filp, loff_t start, loff_t end,
                         int datasync);
-ssize_t v9fs_file_write_internal(struct inode *, struct p9_fid *,
-                                const char __user *, size_t, loff_t *, int);
 int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode);
 int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode);
 static inline void v9fs_invalidate_inode_attr(struct inode *inode)
index ff1a5bac420098d528a46c6cccecfa1caa73c421..2e38f9a5b472874ea7e3991b03e7ad33fdc88aa7 100644 (file)
  */
 static int v9fs_fid_readpage(struct p9_fid *fid, struct page *page)
 {
-       int retval;
-       loff_t offset;
-       char *buffer;
-       struct inode *inode;
+       struct inode *inode = page->mapping->host;
+       struct bio_vec bvec = {.bv_page = page, .bv_len = PAGE_SIZE};
+       struct iov_iter to;
+       int retval, err;
 
-       inode = page->mapping->host;
        p9_debug(P9_DEBUG_VFS, "\n");
 
        BUG_ON(!PageLocked(page));
@@ -65,16 +64,16 @@ static int v9fs_fid_readpage(struct p9_fid *fid, struct page *page)
        if (retval == 0)
                return retval;
 
-       buffer = kmap(page);
-       offset = page_offset(page);
+       iov_iter_bvec(&to, ITER_BVEC | READ, &bvec, 1, PAGE_SIZE);
 
-       retval = v9fs_fid_readn(fid, buffer, NULL, PAGE_CACHE_SIZE, offset);
-       if (retval < 0) {
+       retval = p9_client_read(fid, page_offset(page), &to, &err);
+       if (err) {
                v9fs_uncache_page(inode, page);
+               retval = err;
                goto done;
        }
 
-       memset(buffer + retval, 0, PAGE_CACHE_SIZE - retval);
+       zero_user(page, retval, PAGE_SIZE - retval);
        flush_dcache_page(page);
        SetPageUptodate(page);
 
@@ -82,7 +81,6 @@ static int v9fs_fid_readpage(struct p9_fid *fid, struct page *page)
        retval = 0;
 
 done:
-       kunmap(page);
        unlock_page(page);
        return retval;
 }
@@ -161,41 +159,32 @@ static void v9fs_invalidate_page(struct page *page, unsigned int offset,
 
 static int v9fs_vfs_writepage_locked(struct page *page)
 {
-       char *buffer;
-       int retval, len;
-       loff_t offset, size;
-       mm_segment_t old_fs;
-       struct v9fs_inode *v9inode;
        struct inode *inode = page->mapping->host;
+       struct v9fs_inode *v9inode = V9FS_I(inode);
+       loff_t size = i_size_read(inode);
+       struct iov_iter from;
+       struct bio_vec bvec;
+       int err, len;
 
-       v9inode = V9FS_I(inode);
-       size = i_size_read(inode);
        if (page->index == size >> PAGE_CACHE_SHIFT)
                len = size & ~PAGE_CACHE_MASK;
        else
                len = PAGE_CACHE_SIZE;
 
-       set_page_writeback(page);
-
-       buffer = kmap(page);
-       offset = page_offset(page);
+       bvec.bv_page = page;
+       bvec.bv_offset = 0;
+       bvec.bv_len = len;
+       iov_iter_bvec(&from, ITER_BVEC | WRITE, &bvec, 1, len);
 
-       old_fs = get_fs();
-       set_fs(get_ds());
        /* We should have writeback_fid always set */
        BUG_ON(!v9inode->writeback_fid);
 
-       retval = v9fs_file_write_internal(inode,
-                                         v9inode->writeback_fid,
-                                         (__force const char __user *)buffer,
-                                         len, &offset, 0);
-       if (retval > 0)
-               retval = 0;
+       set_page_writeback(page);
+
+       p9_client_write(v9inode->writeback_fid, page_offset(page), &from, &err);
 
-       set_fs(old_fs);
-       kunmap(page);
        end_page_writeback(page);
-       return retval;
+       return err;
 }
 
 static int v9fs_vfs_writepage(struct page *page, struct writeback_control *wbc)
@@ -261,16 +250,21 @@ static int v9fs_launder_page(struct page *page)
 static ssize_t
 v9fs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, loff_t pos)
 {
-       /*
-        * FIXME
-        * Now that we do caching with cache mode enabled, We need
-        * to support direct IO
-        */
-       p9_debug(P9_DEBUG_VFS, "v9fs_direct_IO: v9fs_direct_IO (%pD) off/no(%lld/%lu) EINVAL\n",
-                iocb->ki_filp,
-                (long long)pos, iter->nr_segs);
-
-       return -EINVAL;
+       struct file *file = iocb->ki_filp;
+       ssize_t n;
+       int err = 0;
+       if (rw & WRITE) {
+               n = p9_client_write(file->private_data, pos, iter, &err);
+               if (n) {
+                       struct inode *inode = file_inode(file);
+                       loff_t i_size = i_size_read(inode);
+                       if (pos + n > i_size)
+                               inode_add_bytes(inode, pos + n - i_size);
+               }
+       } else {
+               n = p9_client_read(file->private_data, pos, iter, &err);
+       }
+       return n ? n : err;
 }
 
 static int v9fs_write_begin(struct file *filp, struct address_space *mapping,
index 4f1151088ebe8779da1af2173818c0088afb2cd0..76c3b1ab6361d69b12f069ed7e9d68b48751eb82 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/inet.h>
 #include <linux/idr.h>
 #include <linux/slab.h>
+#include <linux/uio.h>
 #include <net/9p/9p.h>
 #include <net/9p/client.h>
 
@@ -115,6 +116,7 @@ static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx)
        int buflen;
        int reclen = 0;
        struct p9_rdir *rdir;
+       struct kvec kvec;
 
        p9_debug(P9_DEBUG_VFS, "name %pD\n", file);
        fid = file->private_data;
@@ -124,16 +126,21 @@ static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx)
        rdir = v9fs_alloc_rdir_buf(file, buflen);
        if (!rdir)
                return -ENOMEM;
+       kvec.iov_base = rdir->buf;
+       kvec.iov_len = buflen;
 
        while (1) {
                if (rdir->tail == rdir->head) {
-                       err = v9fs_file_readn(file, rdir->buf, NULL,
-                                                       buflen, ctx->pos);
-                       if (err <= 0)
+                       struct iov_iter to;
+                       int n;
+                       iov_iter_kvec(&to, READ | ITER_KVEC, &kvec, 1, buflen);
+                       n = p9_client_read(file->private_data, ctx->pos, &to,
+                                          &err);
+                       if (err)
                                return err;
 
                        rdir->head = 0;
-                       rdir->tail = err;
+                       rdir->tail = n;
                }
                while (rdir->head < rdir->tail) {
                        p9stat_init(&st);
index b40133796b8734d32cf5376b12d1e01672af85db..d7fcb775311e5a1697a2d8866a5a9f2bb25eb99a 100644 (file)
@@ -36,6 +36,8 @@
 #include <linux/utsname.h>
 #include <asm/uaccess.h>
 #include <linux/idr.h>
+#include <linux/uio.h>
+#include <linux/slab.h>
 #include <net/9p/9p.h>
 #include <net/9p/client.h>
 
@@ -285,6 +287,7 @@ static int v9fs_file_getlock(struct file *filp, struct file_lock *fl)
                        fl->fl_end = glock.start + glock.length - 1;
                fl->fl_pid = glock.proc_id;
        }
+       kfree(glock.client_id);
        return res;
 }
 
@@ -363,63 +366,6 @@ out_err:
        return ret;
 }
 
-/**
- * v9fs_fid_readn - read from a fid
- * @fid: fid to read
- * @data: data buffer to read data into
- * @udata: user data buffer to read data into
- * @count: size of buffer
- * @offset: offset at which to read data
- *
- */
-ssize_t
-v9fs_fid_readn(struct p9_fid *fid, char *data, char __user *udata, u32 count,
-              u64 offset)
-{
-       int n, total, size;
-
-       p9_debug(P9_DEBUG_VFS, "fid %d offset %llu count %d\n",
-                fid->fid, (long long unsigned)offset, count);
-       n = 0;
-       total = 0;
-       size = fid->iounit ? fid->iounit : fid->clnt->msize - P9_IOHDRSZ;
-       do {
-               n = p9_client_read(fid, data, udata, offset, count);
-               if (n <= 0)
-                       break;
-
-               if (data)
-                       data += n;
-               if (udata)
-                       udata += n;
-
-               offset += n;
-               count -= n;
-               total += n;
-       } while (count > 0 && n == size);
-
-       if (n < 0)
-               total = n;
-
-       return total;
-}
-
-/**
- * v9fs_file_readn - read from a file
- * @filp: file pointer to read
- * @data: data buffer to read data into
- * @udata: user data buffer to read data into
- * @count: size of buffer
- * @offset: offset at which to read data
- *
- */
-ssize_t
-v9fs_file_readn(struct file *filp, char *data, char __user *udata, u32 count,
-              u64 offset)
-{
-       return v9fs_fid_readn(filp->private_data, data, udata, count, offset);
-}
-
 /**
  * v9fs_file_read - read from a file
  * @filp: file pointer to read
@@ -430,69 +376,22 @@ v9fs_file_readn(struct file *filp, char *data, char __user *udata, u32 count,
  */
 
 static ssize_t
-v9fs_file_read(struct file *filp, char __user *udata, size_t count,
-              loff_t * offset)
+v9fs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
 {
-       int ret;
-       struct p9_fid *fid;
-       size_t size;
+       struct p9_fid *fid = iocb->ki_filp->private_data;
+       int ret, err;
 
-       p9_debug(P9_DEBUG_VFS, "count %zu offset %lld\n", count, *offset);
-       fid = filp->private_data;
+       p9_debug(P9_DEBUG_VFS, "count %zu offset %lld\n",
+                iov_iter_count(to), iocb->ki_pos);
 
-       size = fid->iounit ? fid->iounit : fid->clnt->msize - P9_IOHDRSZ;
-       if (count > size)
-               ret = v9fs_file_readn(filp, NULL, udata, count, *offset);
-       else
-               ret = p9_client_read(fid, NULL, udata, *offset, count);
-
-       if (ret > 0)
-               *offset += ret;
+       ret = p9_client_read(fid, iocb->ki_pos, to, &err);
+       if (!ret)
+               return err;
 
+       iocb->ki_pos += ret;
        return ret;
 }
 
-ssize_t
-v9fs_file_write_internal(struct inode *inode, struct p9_fid *fid,
-                        const char __user *data, size_t count,
-                        loff_t *offset, int invalidate)
-{
-       int n;
-       loff_t i_size;
-       size_t total = 0;
-       loff_t origin = *offset;
-       unsigned long pg_start, pg_end;
-
-       p9_debug(P9_DEBUG_VFS, "data %p count %d offset %x\n",
-                data, (int)count, (int)*offset);
-
-       do {
-               n = p9_client_write(fid, NULL, data+total, origin+total, count);
-               if (n <= 0)
-                       break;
-               count -= n;
-               total += n;
-       } while (count > 0);
-
-       if (invalidate && (total > 0)) {
-               pg_start = origin >> PAGE_CACHE_SHIFT;
-               pg_end = (origin + total - 1) >> PAGE_CACHE_SHIFT;
-               if (inode->i_mapping && inode->i_mapping->nrpages)
-                       invalidate_inode_pages2_range(inode->i_mapping,
-                                                     pg_start, pg_end);
-               *offset += total;
-               i_size = i_size_read(inode);
-               if (*offset > i_size) {
-                       inode_add_bytes(inode, *offset - i_size);
-                       i_size_write(inode, *offset);
-               }
-       }
-       if (n < 0)
-               return n;
-
-       return total;
-}
-
 /**
  * v9fs_file_write - write to a file
  * @filp: file pointer to write
@@ -502,35 +401,45 @@ v9fs_file_write_internal(struct inode *inode, struct p9_fid *fid,
  *
  */
 static ssize_t
-v9fs_file_write(struct file *filp, const char __user * data,
-               size_t count, loff_t *offset)
+v9fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
 {
+       struct file *file = iocb->ki_filp;
        ssize_t retval = 0;
-       loff_t origin = *offset;
+       loff_t origin = iocb->ki_pos;
+       size_t count = iov_iter_count(from);
+       int err = 0;
 
-
-       retval = generic_write_checks(filp, &origin, &count, 0);
+       retval = generic_write_checks(file, &origin, &count, 0);
        if (retval)
-               goto out;
+               return retval;
+
+       iov_iter_truncate(from, count);
 
-       retval = -EINVAL;
-       if ((ssize_t) count < 0)
-               goto out;
-       retval = 0;
        if (!count)
-               goto out;
+               return 0;
 
-       retval = v9fs_file_write_internal(file_inode(filp),
-                                       filp->private_data,
-                                       data, count, &origin, 1);
-       /* update offset on successful write */
-       if (retval > 0)
-               *offset = origin;
-out:
-       return retval;
+       retval = p9_client_write(file->private_data, origin, from, &err);
+       if (retval > 0) {
+               struct inode *inode = file_inode(file);
+               loff_t i_size;
+               unsigned long pg_start, pg_end;
+               pg_start = origin >> PAGE_CACHE_SHIFT;
+               pg_end = (origin + retval - 1) >> PAGE_CACHE_SHIFT;
+               if (inode->i_mapping && inode->i_mapping->nrpages)
+                       invalidate_inode_pages2_range(inode->i_mapping,
+                                                     pg_start, pg_end);
+               origin += retval;
+               i_size = i_size_read(inode);
+               iocb->ki_pos = origin;
+               if (origin > i_size) {
+                       inode_add_bytes(inode, origin - i_size);
+                       i_size_write(inode, origin);
+               }
+               return retval;
+       }
+       return err;
 }
 
-
 static int v9fs_file_fsync(struct file *filp, loff_t start, loff_t end,
                           int datasync)
 {
@@ -657,44 +566,6 @@ out_unlock:
        return VM_FAULT_NOPAGE;
 }
 
-static ssize_t
-v9fs_direct_read(struct file *filp, char __user *udata, size_t count,
-                loff_t *offsetp)
-{
-       loff_t size, offset;
-       struct inode *inode;
-       struct address_space *mapping;
-
-       offset = *offsetp;
-       mapping = filp->f_mapping;
-       inode = mapping->host;
-       if (!count)
-               return 0;
-       size = i_size_read(inode);
-       if (offset < size)
-               filemap_write_and_wait_range(mapping, offset,
-                                            offset + count - 1);
-
-       return v9fs_file_read(filp, udata, count, offsetp);
-}
-
-/**
- * v9fs_cached_file_read - read from a file
- * @filp: file pointer to read
- * @data: user data buffer to read data into
- * @count: size of buffer
- * @offset: offset at which to read data
- *
- */
-static ssize_t
-v9fs_cached_file_read(struct file *filp, char __user *data, size_t count,
-                     loff_t *offset)
-{
-       if (filp->f_flags & O_DIRECT)
-               return v9fs_direct_read(filp, data, count, offset);
-       return new_sync_read(filp, data, count, offset);
-}
-
 /**
  * v9fs_mmap_file_read - read from a file
  * @filp: file pointer to read
@@ -704,84 +575,12 @@ v9fs_cached_file_read(struct file *filp, char __user *data, size_t count,
  *
  */
 static ssize_t
-v9fs_mmap_file_read(struct file *filp, char __user *data, size_t count,
-                     loff_t *offset)
+v9fs_mmap_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
 {
        /* TODO: Check if there are dirty pages */
-       return v9fs_file_read(filp, data, count, offset);
+       return v9fs_file_read_iter(iocb, to);
 }
 
-static ssize_t
-v9fs_direct_write(struct file *filp, const char __user * data,
-                 size_t count, loff_t *offsetp)
-{
-       loff_t offset;
-       ssize_t retval;
-       struct inode *inode;
-       struct address_space *mapping;
-
-       offset = *offsetp;
-       mapping = filp->f_mapping;
-       inode = mapping->host;
-       if (!count)
-               return 0;
-
-       mutex_lock(&inode->i_mutex);
-       retval = filemap_write_and_wait_range(mapping, offset,
-                                             offset + count - 1);
-       if (retval)
-               goto err_out;
-       /*
-        * After a write we want buffered reads to be sure to go to disk to get
-        * the new data.  We invalidate clean cached page from the region we're
-        * about to write.  We do this *before* the write so that if we fail
-        * here we fall back to buffered write
-        */
-       if (mapping->nrpages) {
-               pgoff_t pg_start = offset >> PAGE_CACHE_SHIFT;
-               pgoff_t pg_end   = (offset + count - 1) >> PAGE_CACHE_SHIFT;
-
-               retval = invalidate_inode_pages2_range(mapping,
-                                                       pg_start, pg_end);
-               /*
-                * If a page can not be invalidated, fall back
-                * to buffered write.
-                */
-               if (retval) {
-                       if (retval == -EBUSY)
-                               goto buff_write;
-                       goto err_out;
-               }
-       }
-       retval = v9fs_file_write(filp, data, count, offsetp);
-err_out:
-       mutex_unlock(&inode->i_mutex);
-       return retval;
-
-buff_write:
-       mutex_unlock(&inode->i_mutex);
-       return new_sync_write(filp, data, count, offsetp);
-}
-
-/**
- * v9fs_cached_file_write - write to a file
- * @filp: file pointer to write
- * @data: data buffer to write data from
- * @count: size of buffer
- * @offset: offset at which to write data
- *
- */
-static ssize_t
-v9fs_cached_file_write(struct file *filp, const char __user * data,
-                      size_t count, loff_t *offset)
-{
-
-       if (filp->f_flags & O_DIRECT)
-               return v9fs_direct_write(filp, data, count, offset);
-       return new_sync_write(filp, data, count, offset);
-}
-
-
 /**
  * v9fs_mmap_file_write - write to a file
  * @filp: file pointer to write
@@ -791,14 +590,13 @@ v9fs_cached_file_write(struct file *filp, const char __user * data,
  *
  */
 static ssize_t
-v9fs_mmap_file_write(struct file *filp, const char __user *data,
-                      size_t count, loff_t *offset)
+v9fs_mmap_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
 {
        /*
         * TODO: invalidate mmaps on filp's inode between
         * offset and offset+count
         */
-       return v9fs_file_write(filp, data, count, offset);
+       return v9fs_file_write_iter(iocb, from);
 }
 
 static void v9fs_mmap_vm_close(struct vm_area_struct *vma)
@@ -843,8 +641,6 @@ static const struct vm_operations_struct v9fs_mmap_file_vm_ops = {
 
 const struct file_operations v9fs_cached_file_operations = {
        .llseek = generic_file_llseek,
-       .read = v9fs_cached_file_read,
-       .write = v9fs_cached_file_write,
        .read_iter = generic_file_read_iter,
        .write_iter = generic_file_write_iter,
        .open = v9fs_file_open,
@@ -856,8 +652,6 @@ const struct file_operations v9fs_cached_file_operations = {
 
 const struct file_operations v9fs_cached_file_operations_dotl = {
        .llseek = generic_file_llseek,
-       .read = v9fs_cached_file_read,
-       .write = v9fs_cached_file_write,
        .read_iter = generic_file_read_iter,
        .write_iter = generic_file_write_iter,
        .open = v9fs_file_open,
@@ -870,8 +664,8 @@ const struct file_operations v9fs_cached_file_operations_dotl = {
 
 const struct file_operations v9fs_file_operations = {
        .llseek = generic_file_llseek,
-       .read = v9fs_file_read,
-       .write = v9fs_file_write,
+       .read_iter = v9fs_file_read_iter,
+       .write_iter = v9fs_file_write_iter,
        .open = v9fs_file_open,
        .release = v9fs_dir_release,
        .lock = v9fs_file_lock,
@@ -881,8 +675,8 @@ const struct file_operations v9fs_file_operations = {
 
 const struct file_operations v9fs_file_operations_dotl = {
        .llseek = generic_file_llseek,
-       .read = v9fs_file_read,
-       .write = v9fs_file_write,
+       .read_iter = v9fs_file_read_iter,
+       .write_iter = v9fs_file_write_iter,
        .open = v9fs_file_open,
        .release = v9fs_dir_release,
        .lock = v9fs_file_lock_dotl,
@@ -893,8 +687,8 @@ const struct file_operations v9fs_file_operations_dotl = {
 
 const struct file_operations v9fs_mmap_file_operations = {
        .llseek = generic_file_llseek,
-       .read = v9fs_mmap_file_read,
-       .write = v9fs_mmap_file_write,
+       .read_iter = v9fs_mmap_file_read_iter,
+       .write_iter = v9fs_mmap_file_write_iter,
        .open = v9fs_file_open,
        .release = v9fs_dir_release,
        .lock = v9fs_file_lock,
@@ -904,8 +698,8 @@ const struct file_operations v9fs_mmap_file_operations = {
 
 const struct file_operations v9fs_mmap_file_operations_dotl = {
        .llseek = generic_file_llseek,
-       .read = v9fs_mmap_file_read,
-       .write = v9fs_mmap_file_write,
+       .read_iter = v9fs_mmap_file_read_iter,
+       .write_iter = v9fs_mmap_file_write_iter,
        .open = v9fs_file_open,
        .release = v9fs_dir_release,
        .lock = v9fs_file_lock_dotl,
index f95e01e058e4de657b3cd85aafc233f0565c6e16..0cf44b6cccd6ee7dd131033845c7619ad778ab89 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
+#include <linux/uio.h>
 #include <net/9p/9p.h>
 #include <net/9p/client.h>
 
@@ -25,50 +26,34 @@ ssize_t v9fs_fid_xattr_get(struct p9_fid *fid, const char *name,
                           void *buffer, size_t buffer_size)
 {
        ssize_t retval;
-       int msize, read_count;
-       u64 offset = 0, attr_size;
+       u64 attr_size;
        struct p9_fid *attr_fid;
+       struct kvec kvec = {.iov_base = buffer, .iov_len = buffer_size};
+       struct iov_iter to;
+       int err;
+
+       iov_iter_kvec(&to, READ | ITER_KVEC, &kvec, 1, buffer_size);
 
        attr_fid = p9_client_xattrwalk(fid, name, &attr_size);
        if (IS_ERR(attr_fid)) {
                retval = PTR_ERR(attr_fid);
                p9_debug(P9_DEBUG_VFS, "p9_client_attrwalk failed %zd\n",
                         retval);
-               attr_fid = NULL;
-               goto error;
-       }
-       if (!buffer_size) {
-               /* request to get the attr_size */
-               retval = attr_size;
-               goto error;
+               return retval;
        }
        if (attr_size > buffer_size) {
-               retval = -ERANGE;
-               goto error;
-       }
-       msize = attr_fid->clnt->msize;
-       while (attr_size) {
-               if (attr_size > (msize - P9_IOHDRSZ))
-                       read_count = msize - P9_IOHDRSZ;
+               if (!buffer_size) /* request to get the attr_size */
+                       retval = attr_size;
                else
-                       read_count = attr_size;
-               read_count = p9_client_read(attr_fid, ((char *)buffer)+offset,
-                                       NULL, offset, read_count);
-               if (read_count < 0) {
-                       /* error in xattr read */
-                       retval = read_count;
-                       goto error;
-               }
-               offset += read_count;
-               attr_size -= read_count;
+                       retval = -ERANGE;
+       } else {
+               iov_iter_truncate(&to, attr_size);
+               retval = p9_client_read(attr_fid, 0, &to, &err);
+               if (err)
+                       retval = err;
        }
-       /* Total read xattr bytes */
-       retval = offset;
-error:
-       if (attr_fid)
-               p9_client_clunk(attr_fid);
+       p9_client_clunk(attr_fid);
        return retval;
-
 }
 
 
@@ -120,8 +105,11 @@ int v9fs_xattr_set(struct dentry *dentry, const char *name,
 int v9fs_fid_xattr_set(struct p9_fid *fid, const char *name,
                   const void *value, size_t value_len, int flags)
 {
-       u64 offset = 0;
-       int retval, msize, write_count;
+       struct kvec kvec = {.iov_base = (void *)value, .iov_len = value_len};
+       struct iov_iter from;
+       int retval;
+
+       iov_iter_kvec(&from, WRITE | ITER_KVEC, &kvec, 1, value_len);
 
        p9_debug(P9_DEBUG_VFS, "name = %s value_len = %zu flags = %d\n",
                 name, value_len, flags);
@@ -135,29 +123,11 @@ int v9fs_fid_xattr_set(struct p9_fid *fid, const char *name,
         * On success fid points to xattr
         */
        retval = p9_client_xattrcreate(fid, name, value_len, flags);
-       if (retval < 0) {
+       if (retval < 0)
                p9_debug(P9_DEBUG_VFS, "p9_client_xattrcreate failed %d\n",
                         retval);
-               goto err;
-       }
-       msize = fid->clnt->msize;
-       while (value_len) {
-               if (value_len > (msize - P9_IOHDRSZ))
-                       write_count = msize - P9_IOHDRSZ;
-               else
-                       write_count = value_len;
-               write_count = p9_client_write(fid, ((char *)value)+offset,
-                                       NULL, offset, write_count);
-               if (write_count < 0) {
-                       /* error in xattr write */
-                       retval = write_count;
-                       goto err;
-               }
-               offset += write_count;
-               value_len -= write_count;
-       }
-       retval = 0;
-err:
+       else
+               p9_client_write(fid, 0, &from, &retval);
        p9_client_clunk(fid);
        return retval;
 }
index 07c9edce5aa768ddeb7ae203c8c9cab489ea8417..46c0d5671cd541d8bafdc9327f2fbf99d0f5133a 100644 (file)
 
 const struct file_operations adfs_file_operations = {
        .llseek         = generic_file_llseek,
-       .read           = new_sync_read,
        .read_iter      = generic_file_read_iter,
        .mmap           = generic_file_mmap,
        .fsync          = generic_file_fsync,
-       .write          = new_sync_write,
        .write_iter     = generic_file_write_iter,
        .splice_read    = generic_file_splice_read,
 };
index 3aa7eb66547ea31b7556c1502d3900dce0aa80dd..7c1a3d4c19c23cd0fd2e9452d813b1014f0233fd 100644 (file)
@@ -969,9 +969,7 @@ int affs_file_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
 }
 const struct file_operations affs_file_operations = {
        .llseek         = generic_file_llseek,
-       .read           = new_sync_read,
        .read_iter      = generic_file_read_iter,
-       .write          = new_sync_write,
        .write_iter     = generic_file_write_iter,
        .mmap           = generic_file_mmap,
        .open           = affs_file_open,
index 932ce07948b387d7aa75dffb3a9de1e21f1f50b8..999bc3caec9276b8148448d4ec2eadb0badbf3f0 100644 (file)
@@ -31,8 +31,6 @@ const struct file_operations afs_file_operations = {
        .open           = afs_open,
        .release        = afs_release,
        .llseek         = generic_file_llseek,
-       .read           = new_sync_read,
-       .write          = new_sync_write,
        .read_iter      = generic_file_read_iter,
        .write_iter     = afs_file_write,
        .mmap           = generic_file_readonly_mmap,
index 1ab60010cf6c75b52945bdf884aa5088a536434f..5785c4b58fea5ffdeae17d43b6b00df2572dc638 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -692,8 +692,7 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
        nr_events *= 2;
 
        /* Prevent overflows */
-       if ((nr_events > (0x10000000U / sizeof(struct io_event))) ||
-           (nr_events > (0x10000000U / sizeof(struct kiocb)))) {
+       if (nr_events > (0x10000000U / sizeof(struct io_event))) {
                pr_debug("ENOMEM: nr_events too high\n");
                return ERR_PTR(-EINVAL);
        }
@@ -1356,8 +1355,6 @@ SYSCALL_DEFINE1(io_destroy, aio_context_t, ctx)
        return -EINVAL;
 }
 
-typedef ssize_t (aio_rw_op)(struct kiocb *, const struct iovec *,
-                           unsigned long, loff_t);
 typedef ssize_t (rw_iter_op)(struct kiocb *, struct iov_iter *);
 
 static int aio_setup_vectored_rw(int rw, char __user *buf, size_t len,
@@ -1386,7 +1383,6 @@ static ssize_t aio_run_iocb(struct kiocb *req, unsigned opcode,
        ssize_t ret;
        int rw;
        fmode_t mode;
-       aio_rw_op *rw_op;
        rw_iter_op *iter_op;
        struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs;
        struct iov_iter iter;
@@ -1396,7 +1392,6 @@ static ssize_t aio_run_iocb(struct kiocb *req, unsigned opcode,
        case IOCB_CMD_PREADV:
                mode    = FMODE_READ;
                rw      = READ;
-               rw_op   = file->f_op->aio_read;
                iter_op = file->f_op->read_iter;
                goto rw_common;
 
@@ -1404,14 +1399,13 @@ static ssize_t aio_run_iocb(struct kiocb *req, unsigned opcode,
        case IOCB_CMD_PWRITEV:
                mode    = FMODE_WRITE;
                rw      = WRITE;
-               rw_op   = file->f_op->aio_write;
                iter_op = file->f_op->write_iter;
                goto rw_common;
 rw_common:
                if (unlikely(!(file->f_mode & mode)))
                        return -EBADF;
 
-               if (!rw_op && !iter_op)
+               if (!iter_op)
                        return -EINVAL;
 
                if (opcode == IOCB_CMD_PREADV || opcode == IOCB_CMD_PWRITEV)
@@ -1431,21 +1425,10 @@ rw_common:
 
                len = ret;
 
-               /* XXX: move/kill - rw_verify_area()? */
-               /* This matches the pread()/pwrite() logic */
-               if (req->ki_pos < 0) {
-                       ret = -EINVAL;
-                       break;
-               }
-
                if (rw == WRITE)
                        file_start_write(file);
 
-               if (iter_op) {
-                       ret = iter_op(req, &iter);
-               } else {
-                       ret = rw_op(req, iter.iov, iter.nr_segs, req->ki_pos);
-               }
+               ret = iter_op(req, &iter);
 
                if (rw == WRITE)
                        file_end_write(file);
index 8e98cf954babb8944a32fdc58fd3c38760933a5a..d10e619632ab48b30390062455eef4b543b7c183 100644 (file)
@@ -213,7 +213,7 @@ void autofs4_clean_ino(struct autofs_info *);
 
 static inline int autofs_prepare_pipe(struct file *pipe)
 {
-       if (!pipe->f_op->write)
+       if (!(pipe->f_mode & FMODE_CAN_WRITE))
                return -EINVAL;
        if (!S_ISFIFO(file_inode(pipe)->i_mode))
                return -EINVAL;
index 116fd38ee472c74f243c05428969c2bd1bbe85e2..2ad05ab93db86efe0e4d0432b7ed8f1f37a0dd52 100644 (file)
@@ -70,7 +70,7 @@ static int autofs4_write(struct autofs_sb_info *sbi,
 
        mutex_lock(&sbi->pipe_mutex);
        while (bytes &&
-              (wr = file->f_op->write(file,data,bytes,&file->f_pos)) > 0) {
+              (wr = __vfs_write(file,data,bytes,&file->f_pos)) > 0) {
                data += wr;
                bytes -= wr;
        }
index e7f88ace1a2508d260ea8feae3addc5e2752980c..97f1b51601550e38c8c4e45bf49c4336da04bed9 100644 (file)
@@ -23,9 +23,7 @@
 
 const struct file_operations bfs_file_operations = {
        .llseek         = generic_file_llseek,
-       .read           = new_sync_read,
        .read_iter      = generic_file_read_iter,
-       .write          = new_sync_write,
        .write_iter     = generic_file_write_iter,
        .mmap           = generic_file_mmap,
        .splice_read    = generic_file_splice_read,
index 2e522aed6584d3a7837155897b2a47085b5ed303..b5e87896f517d17aea743eec62cdfeada14db203 100644 (file)
@@ -1659,8 +1659,6 @@ const struct file_operations def_blk_fops = {
        .open           = blkdev_open,
        .release        = blkdev_close,
        .llseek         = block_llseek,
-       .read           = new_sync_read,
-       .write          = new_sync_write,
        .read_iter      = blkdev_read_iter,
        .write_iter     = blkdev_write_iter,
        .mmap           = generic_file_mmap,
index aee18f84e3159c1e369a0c14eff0baad8ddbb59a..cdc801c8510570a650a17212427b92d35823fab5 100644 (file)
@@ -2806,8 +2806,6 @@ out:
 
 const struct file_operations btrfs_file_operations = {
        .llseek         = btrfs_file_llseek,
-       .read           = new_sync_read,
-       .write          = new_sync_write,
        .read_iter      = generic_file_read_iter,
        .splice_read    = generic_file_splice_read,
        .write_iter     = btrfs_file_write_iter,
index 139f2fea91a0fe8472cf138e900bfe580db43f50..56237ea5fc227580580e8f27a308e97a7fb1c07b 100644 (file)
@@ -1331,8 +1331,6 @@ const struct file_operations ceph_file_fops = {
        .open = ceph_open,
        .release = ceph_release,
        .llseek = ceph_llseek,
-       .read = new_sync_read,
-       .write = new_sync_write,
        .read_iter = ceph_read_iter,
        .write_iter = ceph_write_iter,
        .mmap = ceph_mmap,
index d72fe37f5420e03c7677e86fe2e26d478277d1ae..eaab4b2a05953225ea92075c95dd2e0174d3d75b 100644 (file)
@@ -906,8 +906,6 @@ const struct inode_operations cifs_symlink_inode_ops = {
 };
 
 const struct file_operations cifs_file_ops = {
-       .read = new_sync_read,
-       .write = new_sync_write,
        .read_iter = cifs_loose_read_iter,
        .write_iter = cifs_file_write_iter,
        .open = cifs_open,
@@ -926,8 +924,6 @@ const struct file_operations cifs_file_ops = {
 };
 
 const struct file_operations cifs_file_strict_ops = {
-       .read = new_sync_read,
-       .write = new_sync_write,
        .read_iter = cifs_strict_readv,
        .write_iter = cifs_strict_writev,
        .open = cifs_open,
@@ -947,8 +943,6 @@ const struct file_operations cifs_file_strict_ops = {
 
 const struct file_operations cifs_file_direct_ops = {
        /* BB reevaluate whether they can be done with directio, no cache */
-       .read = new_sync_read,
-       .write = new_sync_write,
        .read_iter = cifs_user_readv,
        .write_iter = cifs_user_writev,
        .open = cifs_open,
@@ -967,8 +961,6 @@ const struct file_operations cifs_file_direct_ops = {
 };
 
 const struct file_operations cifs_file_nobrl_ops = {
-       .read = new_sync_read,
-       .write = new_sync_write,
        .read_iter = cifs_loose_read_iter,
        .write_iter = cifs_file_write_iter,
        .open = cifs_open,
@@ -986,8 +978,6 @@ const struct file_operations cifs_file_nobrl_ops = {
 };
 
 const struct file_operations cifs_file_strict_nobrl_ops = {
-       .read = new_sync_read,
-       .write = new_sync_write,
        .read_iter = cifs_strict_readv,
        .write_iter = cifs_strict_writev,
        .open = cifs_open,
@@ -1006,8 +996,6 @@ const struct file_operations cifs_file_strict_nobrl_ops = {
 
 const struct file_operations cifs_file_direct_nobrl_ops = {
        /* BB reevaluate whether they can be done with directio, no cache */
-       .read = new_sync_read,
-       .write = new_sync_write,
        .read_iter = cifs_user_readv,
        .write_iter = cifs_user_writev,
        .open = cifs_open,
index d244d743a23261c97551d4ee00a30399a2f30b68..1da3805f3ddcdb209a6b357e12aacac35809dda9 100644 (file)
 #include "coda_int.h"
 
 static ssize_t
-coda_file_read(struct file *coda_file, char __user *buf, size_t count, loff_t *ppos)
+coda_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
 {
-       struct coda_file_info *cfi;
-       struct file *host_file;
+       struct file *coda_file = iocb->ki_filp;
+       struct coda_file_info *cfi = CODA_FTOC(coda_file);
 
-       cfi = CODA_FTOC(coda_file);
        BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
-       host_file = cfi->cfi_container;
 
-       if (!host_file->f_op->read)
-               return -EINVAL;
-
-       return host_file->f_op->read(host_file, buf, count, ppos);
+       return vfs_iter_read(cfi->cfi_container, to, &iocb->ki_pos);
 }
 
 static ssize_t
@@ -64,32 +59,25 @@ coda_file_splice_read(struct file *coda_file, loff_t *ppos,
 }
 
 static ssize_t
-coda_file_write(struct file *coda_file, const char __user *buf, size_t count, loff_t *ppos)
+coda_file_write_iter(struct kiocb *iocb, struct iov_iter *to)
 {
-       struct inode *host_inode, *coda_inode = file_inode(coda_file);
-       struct coda_file_info *cfi;
+       struct file *coda_file = iocb->ki_filp;
+       struct inode *coda_inode = file_inode(coda_file);
+       struct coda_file_info *cfi = CODA_FTOC(coda_file);
        struct file *host_file;
        ssize_t ret;
 
-       cfi = CODA_FTOC(coda_file);
        BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
-       host_file = cfi->cfi_container;
-
-       if (!host_file->f_op->write)
-               return -EINVAL;
 
-       host_inode = file_inode(host_file);
+       host_file = cfi->cfi_container;
        file_start_write(host_file);
        mutex_lock(&coda_inode->i_mutex);
-
-       ret = host_file->f_op->write(host_file, buf, count, ppos);
-
-       coda_inode->i_size = host_inode->i_size;
+       ret = vfs_iter_write(cfi->cfi_container, to, &iocb->ki_pos);
+       coda_inode->i_size = file_inode(host_file)->i_size;
        coda_inode->i_blocks = (coda_inode->i_size + 511) >> 9;
        coda_inode->i_mtime = coda_inode->i_ctime = CURRENT_TIME_SEC;
        mutex_unlock(&coda_inode->i_mutex);
        file_end_write(host_file);
-
        return ret;
 }
 
@@ -231,8 +219,8 @@ int coda_fsync(struct file *coda_file, loff_t start, loff_t end, int datasync)
 
 const struct file_operations coda_file_operations = {
        .llseek         = generic_file_llseek,
-       .read           = coda_file_read,
-       .write          = coda_file_write,
+       .read_iter      = coda_file_read_iter,
+       .write_iter     = coda_file_write_iter,
        .mmap           = coda_file_mmap,
        .open           = coda_open,
        .release        = coda_release,
index f319926ddf8cbc5cc90a003628bf500701ce3c25..bbbe139ab28020244f62011f44869d1529cd4b05 100644 (file)
@@ -657,7 +657,7 @@ void do_coredump(const siginfo_t *siginfo)
                 */
                if (!uid_eq(inode->i_uid, current_fsuid()))
                        goto close_fail;
-               if (!cprm.file->f_op->write)
+               if (!(cprm.file->f_mode & FMODE_CAN_WRITE))
                        goto close_fail;
                if (do_truncate(cprm.file->f_path.dentry, 0, 0, cprm.file))
                        goto close_fail;
index 79675089443df98c23de1602d3ca59a887cbb4d4..a65786e26b05ac97dbaab6a6258e533aa842cece 100644 (file)
@@ -358,9 +358,7 @@ const struct file_operations ecryptfs_dir_fops = {
 
 const struct file_operations ecryptfs_main_fops = {
        .llseek = generic_file_llseek,
-       .read = new_sync_read,
        .read_iter = ecryptfs_read_update_atime,
-       .write = new_sync_write,
        .write_iter = generic_file_write_iter,
        .iterate = ecryptfs_readdir,
        .unlocked_ioctl = ecryptfs_unlocked_ioctl,
index 1a376b42d30582c81a9f4d0b3f4dc85b74968cb0..906de66e8e7e067e6179aa3408c6e6aa8ea528b7 100644 (file)
@@ -67,8 +67,6 @@ static int exofs_flush(struct file *file, fl_owner_t id)
 
 const struct file_operations exofs_file_operations = {
        .llseek         = generic_file_llseek,
-       .read           = new_sync_read,
-       .write          = new_sync_write,
        .read_iter      = generic_file_read_iter,
        .write_iter     = generic_file_write_iter,
        .mmap           = generic_file_mmap,
index e31701713516c7f24dee6847badf0e4098b947c8..ef04fdb57dbf823ef6a2dfa9ad46d72727388d50 100644 (file)
@@ -92,8 +92,6 @@ int ext2_fsync(struct file *file, loff_t start, loff_t end, int datasync)
  */
 const struct file_operations ext2_file_operations = {
        .llseek         = generic_file_llseek,
-       .read           = new_sync_read,
-       .write          = new_sync_write,
        .read_iter      = generic_file_read_iter,
        .write_iter     = generic_file_write_iter,
        .unlocked_ioctl = ext2_ioctl,
@@ -111,8 +109,6 @@ const struct file_operations ext2_file_operations = {
 #ifdef CONFIG_FS_DAX
 const struct file_operations ext2_dax_file_operations = {
        .llseek         = generic_file_llseek,
-       .read           = new_sync_read,
-       .write          = new_sync_write,
        .read_iter      = generic_file_read_iter,
        .write_iter     = generic_file_write_iter,
        .unlocked_ioctl = ext2_ioctl,
index a062fa1e1b113e56e7545bb4c6bac7ac1bf7d741..3b8f650de22ce2b917d97d3c0b22717726d593fa 100644 (file)
@@ -50,8 +50,6 @@ static int ext3_release_file (struct inode * inode, struct file * filp)
 
 const struct file_operations ext3_file_operations = {
        .llseek         = generic_file_llseek,
-       .read           = new_sync_read,
-       .write          = new_sync_write,
        .read_iter      = generic_file_read_iter,
        .write_iter     = generic_file_write_iter,
        .unlocked_ioctl = ext3_ioctl,
index 598abbbe678619c347dbe53d8dfe2c8cd6c86c65..9ad03036d9f566d2e932f8fc9f76718f6c289c74 100644 (file)
@@ -607,8 +607,6 @@ loff_t ext4_llseek(struct file *file, loff_t offset, int whence)
 
 const struct file_operations ext4_file_operations = {
        .llseek         = ext4_llseek,
-       .read           = new_sync_read,
-       .write          = new_sync_write,
        .read_iter      = generic_file_read_iter,
        .write_iter     = ext4_file_write_iter,
        .unlocked_ioctl = ext4_ioctl,
@@ -627,8 +625,6 @@ const struct file_operations ext4_file_operations = {
 #ifdef CONFIG_FS_DAX
 const struct file_operations ext4_dax_file_operations = {
        .llseek         = ext4_llseek,
-       .read           = new_sync_read,
-       .write          = new_sync_write,
        .read_iter      = generic_file_read_iter,
        .write_iter     = ext4_file_write_iter,
        .unlocked_ioctl = ext4_ioctl,
index 98dac27bc3f733975fabc96404ab30a916b20e7c..df6a0596eccf210dfefbaaca2cf2f60ca57a7f6b 100644 (file)
@@ -1104,8 +1104,6 @@ long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 
 const struct file_operations f2fs_file_operations = {
        .llseek         = f2fs_llseek,
-       .read           = new_sync_read,
-       .write          = new_sync_write,
        .read_iter      = generic_file_read_iter,
        .write_iter     = generic_file_write_iter,
        .open           = generic_file_open,
index 8429c68e30578150b7dd85667a4b04f8e0d2ed4b..1e98d333879f9952c77af87b1fe1e84177e2f6ee 100644 (file)
@@ -170,8 +170,6 @@ int fat_file_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
 
 const struct file_operations fat_file_operations = {
        .llseek         = generic_file_llseek,
-       .read           = new_sync_read,
-       .write          = new_sync_write,
        .read_iter      = generic_file_read_iter,
        .write_iter     = generic_file_write_iter,
        .mmap           = generic_file_mmap,
index 3f85411b03ce6aac983caa0e0283e8da8848225d..294174dcc2261237fa900432c5c3a7134fda3976 100644 (file)
@@ -168,10 +168,10 @@ struct file *alloc_file(struct path *path, fmode_t mode,
        file->f_inode = path->dentry->d_inode;
        file->f_mapping = path->dentry->d_inode->i_mapping;
        if ((mode & FMODE_READ) &&
-            likely(fop->read || fop->aio_read || fop->read_iter))
+            likely(fop->read || fop->read_iter))
                mode |= FMODE_CAN_READ;
        if ((mode & FMODE_WRITE) &&
-            likely(fop->write || fop->aio_write || fop->write_iter))
+            likely(fop->write || fop->write_iter))
                mode |= FMODE_CAN_WRITE;
        file->f_mode = mode;
        file->f_op = fop;
index b3fa0503223411ff97b3ab5c2f775310b1f3cccb..e5bbf748b6987a922fa211e3edb083346927f3b6 100644 (file)
@@ -88,32 +88,23 @@ static struct list_head *cuse_conntbl_head(dev_t devt)
  * FUSE file.
  */
 
-static ssize_t cuse_read(struct file *file, char __user *buf, size_t count,
-                        loff_t *ppos)
+static ssize_t cuse_read_iter(struct kiocb *kiocb, struct iov_iter *to)
 {
+       struct fuse_io_priv io = { .async = 0, .file = kiocb->ki_filp };
        loff_t pos = 0;
-       struct iovec iov = { .iov_base = buf, .iov_len = count };
-       struct fuse_io_priv io = { .async = 0, .file = file };
-       struct iov_iter ii;
-       iov_iter_init(&ii, READ, &iov, 1, count);
 
-       return fuse_direct_io(&io, &ii, &pos, FUSE_DIO_CUSE);
+       return fuse_direct_io(&io, to, &pos, FUSE_DIO_CUSE);
 }
 
-static ssize_t cuse_write(struct file *file, const char __user *buf,
-                         size_t count, loff_t *ppos)
+static ssize_t cuse_write_iter(struct kiocb *kiocb, struct iov_iter *from)
 {
+       struct fuse_io_priv io = { .async = 0, .file = kiocb->ki_filp };
        loff_t pos = 0;
-       struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = count };
-       struct fuse_io_priv io = { .async = 0, .file = file };
-       struct iov_iter ii;
-       iov_iter_init(&ii, WRITE, &iov, 1, count);
-
        /*
         * No locking or generic_write_checks(), the server is
         * responsible for locking and sanity checks.
         */
-       return fuse_direct_io(&io, &ii, &pos,
+       return fuse_direct_io(&io, from, &pos,
                              FUSE_DIO_WRITE | FUSE_DIO_CUSE);
 }
 
@@ -186,8 +177,8 @@ static long cuse_file_compat_ioctl(struct file *file, unsigned int cmd,
 
 static const struct file_operations cuse_frontend_fops = {
        .owner                  = THIS_MODULE,
-       .read                   = cuse_read,
-       .write                  = cuse_write,
+       .read_iter              = cuse_read_iter,
+       .write_iter             = cuse_write_iter,
        .open                   = cuse_open,
        .release                = cuse_release,
        .unlocked_ioctl         = cuse_file_ioctl,
index 95a2797eef66d8db6edb1c7c4310be292744a427..c8b68ab2e574a86f13fab97f9ed47b14a4e139d6 100644 (file)
@@ -710,28 +710,26 @@ struct fuse_copy_state {
        struct fuse_conn *fc;
        int write;
        struct fuse_req *req;
-       const struct iovec *iov;
+       struct iov_iter *iter;
        struct pipe_buffer *pipebufs;
        struct pipe_buffer *currbuf;
        struct pipe_inode_info *pipe;
        unsigned long nr_segs;
-       unsigned long seglen;
-       unsigned long addr;
        struct page *pg;
        unsigned len;
        unsigned offset;
        unsigned move_pages:1;
 };
 
-static void fuse_copy_init(struct fuse_copy_state *cs, struct fuse_conn *fc,
+static void fuse_copy_init(struct fuse_copy_state *cs,
+                          struct fuse_conn *fc,
                           int write,
-                          const struct iovec *iov, unsigned long nr_segs)
+                          struct iov_iter *iter)
 {
        memset(cs, 0, sizeof(*cs));
        cs->fc = fc;
        cs->write = write;
-       cs->iov = iov;
-       cs->nr_segs = nr_segs;
+       cs->iter = iter;
 }
 
 /* Unmap and put previous page of userspace buffer */
@@ -799,22 +797,16 @@ static int fuse_copy_fill(struct fuse_copy_state *cs)
                        cs->nr_segs++;
                }
        } else {
-               if (!cs->seglen) {
-                       BUG_ON(!cs->nr_segs);
-                       cs->seglen = cs->iov[0].iov_len;
-                       cs->addr = (unsigned long) cs->iov[0].iov_base;
-                       cs->iov++;
-                       cs->nr_segs--;
-               }
-               err = get_user_pages_fast(cs->addr, 1, cs->write, &page);
+               size_t off;
+               err = iov_iter_get_pages(cs->iter, &page, PAGE_SIZE, 1, &off);
                if (err < 0)
                        return err;
-               BUG_ON(err != 1);
+               BUG_ON(!err);
+               cs->len = err;
+               cs->offset = off;
                cs->pg = page;
-               cs->offset = cs->addr % PAGE_SIZE;
-               cs->len = min(PAGE_SIZE - cs->offset, cs->seglen);
-               cs->seglen -= cs->len;
-               cs->addr += cs->len;
+               cs->offset = off;
+               iov_iter_advance(cs->iter, err);
        }
 
        return lock_request(cs->fc, cs->req);
@@ -1363,8 +1355,7 @@ static int fuse_dev_open(struct inode *inode, struct file *file)
        return 0;
 }
 
-static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov,
-                             unsigned long nr_segs, loff_t pos)
+static ssize_t fuse_dev_read(struct kiocb *iocb, struct iov_iter *to)
 {
        struct fuse_copy_state cs;
        struct file *file = iocb->ki_filp;
@@ -1372,9 +1363,12 @@ static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov,
        if (!fc)
                return -EPERM;
 
-       fuse_copy_init(&cs, fc, 1, iov, nr_segs);
+       if (!iter_is_iovec(to))
+               return -EINVAL;
 
-       return fuse_dev_do_read(fc, file, &cs, iov_length(iov, nr_segs));
+       fuse_copy_init(&cs, fc, 1, to);
+
+       return fuse_dev_do_read(fc, file, &cs, iov_iter_count(to));
 }
 
 static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,
@@ -1394,7 +1388,7 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,
        if (!bufs)
                return -ENOMEM;
 
-       fuse_copy_init(&cs, fc, 1, NULL, 0);
+       fuse_copy_init(&cs, fc, 1, NULL);
        cs.pipebufs = bufs;
        cs.pipe = pipe;
        ret = fuse_dev_do_read(fc, in, &cs, len);
@@ -1970,17 +1964,19 @@ static ssize_t fuse_dev_do_write(struct fuse_conn *fc,
        return err;
 }
 
-static ssize_t fuse_dev_write(struct kiocb *iocb, const struct iovec *iov,
-                             unsigned long nr_segs, loff_t pos)
+static ssize_t fuse_dev_write(struct kiocb *iocb, struct iov_iter *from)
 {
        struct fuse_copy_state cs;
        struct fuse_conn *fc = fuse_get_conn(iocb->ki_filp);
        if (!fc)
                return -EPERM;
 
-       fuse_copy_init(&cs, fc, 0, iov, nr_segs);
+       if (!iter_is_iovec(from))
+               return -EINVAL;
+
+       fuse_copy_init(&cs, fc, 0, from);
 
-       return fuse_dev_do_write(fc, &cs, iov_length(iov, nr_segs));
+       return fuse_dev_do_write(fc, &cs, iov_iter_count(from));
 }
 
 static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
@@ -2043,8 +2039,9 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
        }
        pipe_unlock(pipe);
 
-       fuse_copy_init(&cs, fc, 0, NULL, nbuf);
+       fuse_copy_init(&cs, fc, 0, NULL);
        cs.pipebufs = bufs;
+       cs.nr_segs = nbuf;
        cs.pipe = pipe;
 
        if (flags & SPLICE_F_MOVE)
@@ -2232,11 +2229,9 @@ const struct file_operations fuse_dev_operations = {
        .owner          = THIS_MODULE,
        .open           = fuse_dev_open,
        .llseek         = no_llseek,
-       .read           = do_sync_read,
-       .aio_read       = fuse_dev_read,
+       .read_iter      = fuse_dev_read,
        .splice_read    = fuse_dev_splice_read,
-       .write          = do_sync_write,
-       .aio_write      = fuse_dev_write,
+       .write_iter     = fuse_dev_write,
        .splice_write   = fuse_dev_splice_write,
        .poll           = fuse_dev_poll,
        .release        = fuse_dev_release,
index ff102cbf16eab45bdd74eb7cffeafc99a4d7b064..e1afdd7abf90114fffd61da6bcfcc77916afb950 100644 (file)
@@ -1401,55 +1401,33 @@ static ssize_t __fuse_direct_read(struct fuse_io_priv *io,
        return res;
 }
 
-static ssize_t fuse_direct_read(struct file *file, char __user *buf,
-                                    size_t count, loff_t *ppos)
+static ssize_t fuse_direct_read_iter(struct kiocb *iocb, struct iov_iter *to)
 {
-       struct fuse_io_priv io = { .async = 0, .file = file };
-       struct iovec iov = { .iov_base = buf, .iov_len = count };
-       struct iov_iter ii;
-       iov_iter_init(&ii, READ, &iov, 1, count);
-       return __fuse_direct_read(&io, &ii, ppos);
+       struct fuse_io_priv io = { .async = 0, .file = iocb->ki_filp };
+       return __fuse_direct_read(&io, to, &iocb->ki_pos);
 }
 
-static ssize_t __fuse_direct_write(struct fuse_io_priv *io,
-                                  struct iov_iter *iter,
-                                  loff_t *ppos)
+static ssize_t fuse_direct_write_iter(struct kiocb *iocb, struct iov_iter *from)
 {
-       struct file *file = io->file;
-       struct inode *inode = file_inode(file);
-       size_t count = iov_iter_count(iter);
-       ssize_t res;
-
-
-       res = generic_write_checks(file, ppos, &count, 0);
-       if (!res) {
-               iov_iter_truncate(iter, count);
-               res = fuse_direct_io(io, iter, ppos, FUSE_DIO_WRITE);
-       }
-
-       fuse_invalidate_attr(inode);
-
-       return res;
-}
-
-static ssize_t fuse_direct_write(struct file *file, const char __user *buf,
-                                size_t count, loff_t *ppos)
-{
-       struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = count };
+       struct file *file = iocb->ki_filp;
        struct inode *inode = file_inode(file);
-       ssize_t res;
        struct fuse_io_priv io = { .async = 0, .file = file };
-       struct iov_iter ii;
-       iov_iter_init(&ii, WRITE, &iov, 1, count);
+       size_t count = iov_iter_count(from);
+       ssize_t res;
 
        if (is_bad_inode(inode))
                return -EIO;
 
        /* Don't allow parallel writes to the same file */
        mutex_lock(&inode->i_mutex);
-       res = __fuse_direct_write(&io, &ii, ppos);
+       res = generic_write_checks(file, &iocb->ki_pos, &count, 0);
+       if (!res) {
+               iov_iter_truncate(from, count);
+               res = fuse_direct_io(&io, from, &iocb->ki_pos, FUSE_DIO_WRITE);
+       }
+       fuse_invalidate_attr(inode);
        if (res > 0)
-               fuse_write_update_size(inode, *ppos);
+               fuse_write_update_size(inode, iocb->ki_pos);
        mutex_unlock(&inode->i_mutex);
 
        return res;
@@ -2862,10 +2840,17 @@ fuse_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter,
        if (io->async && is_sync_kiocb(iocb))
                io->done = &wait;
 
-       if (rw == WRITE)
-               ret = __fuse_direct_write(io, iter, &pos);
-       else
+       if (rw == WRITE) {
+               ret = generic_write_checks(file, &pos, &count, 0);
+               if (!ret) {
+                       iov_iter_truncate(iter, count);
+                       ret = fuse_direct_io(io, iter, &pos, FUSE_DIO_WRITE);
+               }
+
+               fuse_invalidate_attr(inode);
+       } else {
                ret = __fuse_direct_read(io, iter, &pos);
+       }
 
        if (io->async) {
                fuse_aio_complete(io, ret < 0 ? ret : 0, -1);
@@ -2968,9 +2953,7 @@ out:
 
 static const struct file_operations fuse_file_operations = {
        .llseek         = fuse_file_llseek,
-       .read           = new_sync_read,
        .read_iter      = fuse_file_read_iter,
-       .write          = new_sync_write,
        .write_iter     = fuse_file_write_iter,
        .mmap           = fuse_file_mmap,
        .open           = fuse_open,
@@ -2988,8 +2971,8 @@ static const struct file_operations fuse_file_operations = {
 
 static const struct file_operations fuse_direct_io_file_operations = {
        .llseek         = fuse_file_llseek,
-       .read           = fuse_direct_read,
-       .write          = fuse_direct_write,
+       .read_iter      = fuse_direct_read_iter,
+       .write_iter     = fuse_direct_write_iter,
        .mmap           = fuse_direct_mmap,
        .open           = fuse_open,
        .flush          = fuse_flush,
index 8ec43ab5babf4785470ca246cfff9077c683e5c1..207eb4a8135e656126eb2a50a09e2abea5cd5779 100644 (file)
@@ -1105,9 +1105,7 @@ static int gfs2_flock(struct file *file, int cmd, struct file_lock *fl)
 
 const struct file_operations gfs2_file_fops = {
        .llseek         = gfs2_llseek,
-       .read           = new_sync_read,
        .read_iter      = generic_file_read_iter,
-       .write          = new_sync_write,
        .write_iter     = gfs2_file_write_iter,
        .unlocked_ioctl = gfs2_ioctl,
        .mmap           = gfs2_mmap,
@@ -1137,9 +1135,7 @@ const struct file_operations gfs2_dir_fops = {
 
 const struct file_operations gfs2_file_fops_nolock = {
        .llseek         = gfs2_llseek,
-       .read           = new_sync_read,
        .read_iter      = generic_file_read_iter,
-       .write          = new_sync_write,
        .write_iter     = gfs2_file_write_iter,
        .unlocked_ioctl = gfs2_ioctl,
        .mmap           = gfs2_mmap,
index 98d4ea45bb70aad886641f66d81e0007f0d0e34d..9337065bcc6761280e5abb7b8078811172e3a76b 100644 (file)
@@ -674,9 +674,7 @@ static int hfs_file_fsync(struct file *filp, loff_t start, loff_t end,
 
 static const struct file_operations hfs_file_operations = {
        .llseek         = generic_file_llseek,
-       .read           = new_sync_read,
        .read_iter      = generic_file_read_iter,
-       .write          = new_sync_write,
        .write_iter     = generic_file_write_iter,
        .mmap           = generic_file_mmap,
        .splice_read    = generic_file_splice_read,
index f541196d4ee910a3f9ec6ce26841937c9fa7eb73..5f86cadb0542c074b7015483303d3bdfefe3347f 100644 (file)
@@ -341,9 +341,7 @@ static const struct inode_operations hfsplus_file_inode_operations = {
 
 static const struct file_operations hfsplus_file_operations = {
        .llseek         = generic_file_llseek,
-       .read           = new_sync_read,
        .read_iter      = generic_file_read_iter,
-       .write          = new_sync_write,
        .write_iter     = generic_file_write_iter,
        .mmap           = generic_file_mmap,
        .splice_read    = generic_file_splice_read,
index fd62cae0fdcb66db03712d419c25014312112546..e021188ca110aa9561be325c22724c75034d21f9 100644 (file)
@@ -378,11 +378,9 @@ static int hostfs_fsync(struct file *file, loff_t start, loff_t end,
 
 static const struct file_operations hostfs_file_fops = {
        .llseek         = generic_file_llseek,
-       .read           = new_sync_read,
        .splice_read    = generic_file_splice_read,
        .read_iter      = generic_file_read_iter,
        .write_iter     = generic_file_write_iter,
-       .write          = new_sync_write,
        .mmap           = generic_file_mmap,
        .open           = hostfs_file_open,
        .release        = hostfs_file_release,
index 7f54e5f76cececd4bf76354edb13eb246a81df78..6d8cfe9b52d611b7dadbfa1a38ec7cf3c3b3671c 100644 (file)
@@ -197,9 +197,7 @@ const struct address_space_operations hpfs_aops = {
 const struct file_operations hpfs_file_ops =
 {
        .llseek         = generic_file_llseek,
-       .read           = new_sync_read,
        .read_iter      = generic_file_read_iter,
-       .write          = new_sync_write,
        .write_iter     = generic_file_write_iter,
        .mmap           = generic_file_mmap,
        .release        = hpfs_file_release,
index db76cec3ce21268bbeffcb45c479bfadf7c33e73..45e34908bdb5549d4a4280f123738bb7577feedf 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/security.h>
 #include <linux/magic.h>
 #include <linux/migrate.h>
+#include <linux/uio.h>
 
 #include <asm/uaccess.h>
 
@@ -179,42 +180,33 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
 }
 #endif
 
-static int
+static size_t
 hugetlbfs_read_actor(struct page *page, unsigned long offset,
-                       char __user *buf, unsigned long count,
-                       unsigned long size)
+                       struct iov_iter *to, unsigned long size)
 {
-       char *kaddr;
-       unsigned long left, copied = 0;
+       size_t copied = 0;
        int i, chunksize;
 
-       if (size > count)
-               size = count;
-
        /* Find which 4k chunk and offset with in that chunk */
        i = offset >> PAGE_CACHE_SHIFT;
        offset = offset & ~PAGE_CACHE_MASK;
 
        while (size) {
+               size_t n;
                chunksize = PAGE_CACHE_SIZE;
                if (offset)
                        chunksize -= offset;
                if (chunksize > size)
                        chunksize = size;
-               kaddr = kmap(&page[i]);
-               left = __copy_to_user(buf, kaddr + offset, chunksize);
-               kunmap(&page[i]);
-               if (left) {
-                       copied += (chunksize - left);
-                       break;
-               }
+               n = copy_page_to_iter(&page[i], offset, chunksize, to);
+               copied += n;
+               if (n != chunksize)
+                       return copied;
                offset = 0;
                size -= chunksize;
-               buf += chunksize;
-               copied += chunksize;
                i++;
        }
-       return copied ? copied : -EFAULT;
+       return copied;
 }
 
 /*
@@ -222,39 +214,34 @@ hugetlbfs_read_actor(struct page *page, unsigned long offset,
  * data. Its *very* similar to do_generic_mapping_read(), we can't use that
  * since it has PAGE_CACHE_SIZE assumptions.
  */
-static ssize_t hugetlbfs_read(struct file *filp, char __user *buf,
-                             size_t len, loff_t *ppos)
+static ssize_t hugetlbfs_read_iter(struct kiocb *iocb, struct iov_iter *to)
 {
-       struct hstate *h = hstate_file(filp);
-       struct address_space *mapping = filp->f_mapping;
+       struct file *file = iocb->ki_filp;
+       struct hstate *h = hstate_file(file);
+       struct address_space *mapping = file->f_mapping;
        struct inode *inode = mapping->host;
-       unsigned long index = *ppos >> huge_page_shift(h);
-       unsigned long offset = *ppos & ~huge_page_mask(h);
+       unsigned long index = iocb->ki_pos >> huge_page_shift(h);
+       unsigned long offset = iocb->ki_pos & ~huge_page_mask(h);
        unsigned long end_index;
        loff_t isize;
        ssize_t retval = 0;
 
-       /* validate length */
-       if (len == 0)
-               goto out;
-
-       for (;;) {
+       while (iov_iter_count(to)) {
                struct page *page;
-               unsigned long nr, ret;
-               int ra;
+               size_t nr, copied;
 
                /* nr is the maximum number of bytes to copy from this page */
                nr = huge_page_size(h);
                isize = i_size_read(inode);
                if (!isize)
-                       goto out;
+                       break;
                end_index = (isize - 1) >> huge_page_shift(h);
-               if (index >= end_index) {
-                       if (index > end_index)
-                               goto out;
+               if (index > end_index)
+                       break;
+               if (index == end_index) {
                        nr = ((isize - 1) & ~huge_page_mask(h)) + 1;
                        if (nr <= offset)
-                               goto out;
+                               break;
                }
                nr = nr - offset;
 
@@ -265,39 +252,27 @@ static ssize_t hugetlbfs_read(struct file *filp, char __user *buf,
                         * We have a HOLE, zero out the user-buffer for the
                         * length of the hole or request.
                         */
-                       ret = len < nr ? len : nr;
-                       if (clear_user(buf, ret))
-                               ra = -EFAULT;
-                       else
-                               ra = 0;
+                       copied = iov_iter_zero(nr, to);
                } else {
                        unlock_page(page);
 
                        /*
                         * We have the page, copy it to user space buffer.
                         */
-                       ra = hugetlbfs_read_actor(page, offset, buf, len, nr);
-                       ret = ra;
+                       copied = hugetlbfs_read_actor(page, offset, to, nr);
                        page_cache_release(page);
                }
-               if (ra < 0) {
-                       if (retval == 0)
-                               retval = ra;
-                       goto out;
+               offset += copied;
+               retval += copied;
+               if (copied != nr && iov_iter_count(to)) {
+                       if (!retval)
+                               retval = -EFAULT;
+                       break;
                }
-
-               offset += ret;
-               retval += ret;
-               len -= ret;
                index += offset >> huge_page_shift(h);
                offset &= ~huge_page_mask(h);
-
-               /* short read or no more work */
-               if ((ret != nr) || (len == 0))
-                       break;
        }
-out:
-       *ppos = ((loff_t)index << huge_page_shift(h)) + offset;
+       iocb->ki_pos = ((loff_t)index << huge_page_shift(h)) + offset;
        return retval;
 }
 
@@ -721,7 +696,7 @@ static void init_once(void *foo)
 }
 
 const struct file_operations hugetlbfs_file_operations = {
-       .read                   = hugetlbfs_read,
+       .read_iter              = hugetlbfs_read_iter,
        .mmap                   = hugetlbfs_file_mmap,
        .fsync                  = noop_fsync,
        .get_unmapped_area      = hugetlb_get_unmapped_area,
index 64989ca9ba90b71e3a8d16ff90dda67a913cc988..f509f62e12f6ef85e95b5c159353cba757ef4af1 100644 (file)
@@ -51,9 +51,7 @@ const struct file_operations jffs2_file_operations =
 {
        .llseek =       generic_file_llseek,
        .open =         generic_file_open,
-       .read =         new_sync_read,
        .read_iter =    generic_file_read_iter,
-       .write =        new_sync_write,
        .write_iter =   generic_file_write_iter,
        .unlocked_ioctl=jffs2_ioctl,
        .mmap =         generic_file_readonly_mmap,
index 10815f8dfd8b28c31e045d62d0351013ca442a03..ae46788b97231efecb7eaf7d7c0a0b9c779349ef 100644 (file)
@@ -151,8 +151,6 @@ const struct inode_operations jfs_file_inode_operations = {
 const struct file_operations jfs_file_operations = {
        .open           = jfs_open,
        .llseek         = generic_file_llseek,
-       .write          = new_sync_write,
-       .read           = new_sync_read,
        .read_iter      = generic_file_read_iter,
        .write_iter     = generic_file_write_iter,
        .mmap           = generic_file_mmap,
index 8538752df2f6a7dbb3dad0119e4e8bc47f4a25f4..b2c13f739ffa27b8b8a249cadcd025737a512ce6 100644 (file)
@@ -271,8 +271,6 @@ const struct file_operations logfs_reg_fops = {
        .llseek         = generic_file_llseek,
        .mmap           = generic_file_readonly_mmap,
        .open           = generic_file_open,
-       .read           = new_sync_read,
-       .write          = new_sync_write,
 };
 
 const struct address_space_operations logfs_reg_aops = {
index a967de085ac0f4cf7193101cd4e54a08bb4fff50..6d63e27ec961c6ed03b9bbcd46414d4436e065dd 100644 (file)
@@ -14,9 +14,7 @@
  */
 const struct file_operations minix_file_operations = {
        .llseek         = generic_file_llseek,
-       .read           = new_sync_read,
        .read_iter      = generic_file_read_iter,
-       .write          = new_sync_write,
        .write_iter     = generic_file_write_iter,
        .mmap           = generic_file_mmap,
        .fsync          = generic_file_fsync,
index 1dd7007f974dd97fb0df6d036f85b1f0f9950842..479bf8db264e0cd0f253093f957a2ea32f0012a2 100644 (file)
@@ -98,30 +98,24 @@ out:
 }
 
 static ssize_t
-ncp_file_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
+ncp_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
 {
+       struct file *file = iocb->ki_filp;
        struct inode *inode = file_inode(file);
        size_t already_read = 0;
-       off_t pos;
+       off_t pos = iocb->ki_pos;
        size_t bufsize;
        int error;
-       voidfreepage;
+       void *freepage;
        size_t freelen;
 
        ncp_dbg(1, "enter %pD2\n", file);
 
-       pos = *ppos;
-
-       if ((ssize_t) count < 0) {
-               return -EINVAL;
-       }
-       if (!count)
+       if (!iov_iter_count(to))
                return 0;
        if (pos > inode->i_sb->s_maxbytes)
                return 0;
-       if (pos + count > inode->i_sb->s_maxbytes) {
-               count = inode->i_sb->s_maxbytes - pos;
-       }
+       iov_iter_truncate(to, inode->i_sb->s_maxbytes - pos);
 
        error = ncp_make_open(inode, O_RDONLY);
        if (error) {
@@ -138,31 +132,29 @@ ncp_file_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
                goto outrel;
        error = 0;
        /* First read in as much as possible for each bufsize. */
-       while (already_read < count) {
+       while (iov_iter_count(to)) {
                int read_this_time;
-               size_t to_read = min_t(unsigned int,
+               size_t to_read = min_t(size_t,
                                     bufsize - (pos % bufsize),
-                                    count - already_read);
+                                    iov_iter_count(to));
 
                error = ncp_read_bounce(NCP_SERVER(inode),
                                NCP_FINFO(inode)->file_handle,
-                               pos, to_read, buf, &read_this_time, 
+                               pos, to_read, to, &read_this_time, 
                                freepage, freelen);
                if (error) {
                        error = -EIO;   /* NW errno -> Linux errno */
                        break;
                }
                pos += read_this_time;
-               buf += read_this_time;
                already_read += read_this_time;
 
-               if (read_this_time != to_read) {
+               if (read_this_time != to_read)
                        break;
-               }
        }
        vfree(freepage);
 
-       *ppos = pos;
+       iocb->ki_pos = pos;
 
        file_accessed(file);
 
@@ -173,42 +165,26 @@ outrel:
 }
 
 static ssize_t
-ncp_file_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
+ncp_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
 {
+       struct file *file = iocb->ki_filp;
        struct inode *inode = file_inode(file);
        size_t already_written = 0;
-       off_t pos;
+       loff_t pos = iocb->ki_pos;
+       size_t count = iov_iter_count(from);
        size_t bufsize;
        int errno;
-       voidbouncebuffer;
+       void *bouncebuffer;
 
        ncp_dbg(1, "enter %pD2\n", file);
-       if ((ssize_t) count < 0)
-               return -EINVAL;
-       pos = *ppos;
-       if (file->f_flags & O_APPEND) {
-               pos = i_size_read(inode);
-       }
-
-       if (pos + count > MAX_NON_LFS && !(file->f_flags&O_LARGEFILE)) {
-               if (pos >= MAX_NON_LFS) {
-                       return -EFBIG;
-               }
-               if (count > MAX_NON_LFS - (u32)pos) {
-                       count = MAX_NON_LFS - (u32)pos;
-               }
-       }
-       if (pos >= inode->i_sb->s_maxbytes) {
-               if (count || pos > inode->i_sb->s_maxbytes) {
-                       return -EFBIG;
-               }
-       }
-       if (pos + count > inode->i_sb->s_maxbytes) {
-               count = inode->i_sb->s_maxbytes - pos;
-       }
+       errno = generic_write_checks(file, &pos, &count, 0);
+       if (errno)
+               return errno;
+       iov_iter_truncate(from, count);
        
        if (!count)
                return 0;
+
        errno = ncp_make_open(inode, O_WRONLY);
        if (errno) {
                ncp_dbg(1, "open failed, error=%d\n", errno);
@@ -216,8 +192,6 @@ ncp_file_write(struct file *file, const char __user *buf, size_t count, loff_t *
        }
        bufsize = NCP_SERVER(inode)->buffer_size;
 
-       already_written = 0;
-
        errno = file_update_time(file);
        if (errno)
                goto outrel;
@@ -227,13 +201,13 @@ ncp_file_write(struct file *file, const char __user *buf, size_t count, loff_t *
                errno = -EIO;   /* -ENOMEM */
                goto outrel;
        }
-       while (already_written < count) {
+       while (iov_iter_count(from)) {
                int written_this_time;
-               size_t to_write = min_t(unsigned int,
-                                     bufsize - (pos % bufsize),
-                                     count - already_written);
+               size_t to_write = min_t(size_t,
+                                     bufsize - ((off_t)pos % bufsize),
+                                     iov_iter_count(from));
 
-               if (copy_from_user(bouncebuffer, buf, to_write)) {
+               if (copy_from_iter(bouncebuffer, to_write, from) != to_write) {
                        errno = -EFAULT;
                        break;
                }
@@ -244,16 +218,14 @@ ncp_file_write(struct file *file, const char __user *buf, size_t count, loff_t *
                        break;
                }
                pos += written_this_time;
-               buf += written_this_time;
                already_written += written_this_time;
 
-               if (written_this_time != to_write) {
+               if (written_this_time != to_write)
                        break;
-               }
        }
        vfree(bouncebuffer);
 
-       *ppos = pos;
+       iocb->ki_pos = pos;
 
        if (pos > i_size_read(inode)) {
                mutex_lock(&inode->i_mutex);
@@ -277,8 +249,8 @@ static int ncp_release(struct inode *inode, struct file *file) {
 const struct file_operations ncp_file_operations =
 {
        .llseek         = generic_file_llseek,
-       .read           = ncp_file_read,
-       .write          = ncp_file_write,
+       .read_iter      = ncp_file_read_iter,
+       .write_iter     = ncp_file_write_iter,
        .unlocked_ioctl = ncp_ioctl,
 #ifdef CONFIG_COMPAT
        .compat_ioctl   = ncp_compat_ioctl,
index 482387532f547fbc0e61def87d85c1dfb4b71ebc..2b502a0d79413ef2c01069b8dd228da14ecc354c 100644 (file)
@@ -1001,8 +1001,8 @@ out:
  */
 int
 ncp_read_bounce(struct ncp_server *server, const char *file_id,
-        __u32 offset, __u16 to_read, char __user *target, int *bytes_read,
-        void* bounce, __u32 bufsize)
+        __u32 offset, __u16 to_read, struct iov_iter *to,
+        int *bytes_read, void *bounce, __u32 bufsize)
 {
        int result;
 
@@ -1025,7 +1025,7 @@ ncp_read_bounce(struct ncp_server *server, const char *file_id,
                                 (offset & 1);
                        *bytes_read = len;
                        result = 0;
-                       if (copy_to_user(target, source, len))
+                       if (copy_to_iter(source, len, to) != len)
                                result = -EFAULT;
                }
        }
index 250e443a07f32ec8188aa4f98db5bbeadcf59f19..5233fbc1747a5bf555da56c04917cc418c4390ed 100644 (file)
@@ -53,7 +53,7 @@ static inline int ncp_read_bounce_size(__u32 size) {
        return sizeof(struct ncp_reply_header) + 2 + 2 + size + 8;
 };
 int ncp_read_bounce(struct ncp_server *, const char *, __u32, __u16, 
-               char __user *, int *, void* bounce, __u32 bouncelen);
+               struct iov_iter *, int *, void *bounce, __u32 bouncelen);
 int ncp_read_kernel(struct ncp_server *, const char *, __u32, __u16, 
                char *, int *);
 int ncp_write_kernel(struct ncp_server *, const char *, __u32, __u16,
index 37b15582e0de960a966e80fcda3aa1680caa094d..f6a3adedf0270b7edabb23511746a14bbe6d000c 100644 (file)
@@ -926,8 +926,6 @@ EXPORT_SYMBOL_GPL(nfs_flock);
 
 const struct file_operations nfs_file_operations = {
        .llseek         = nfs_file_llseek,
-       .read           = new_sync_read,
-       .write          = new_sync_write,
        .read_iter      = nfs_file_read,
        .write_iter     = nfs_file_write,
        .mmap           = nfs_file_mmap,
index 8b46389c4c5b814806979b66348121afe0590090..0181cde1d102ab5340ef7be230dc2e3ca036993c 100644 (file)
@@ -170,8 +170,6 @@ const struct file_operations nfs4_file_operations = {
 #else
        .llseek         = nfs_file_llseek,
 #endif
-       .read           = new_sync_read,
-       .write          = new_sync_write,
        .read_iter      = nfs_file_read,
        .write_iter     = nfs_file_write,
        .mmap           = nfs_file_mmap,
index a8c728acb7a809b4078c21146ae1c3759c7f7021..54575e3cc1a24eda326fd19bde268bbc1b187f21 100644 (file)
@@ -143,8 +143,6 @@ static int nilfs_file_mmap(struct file *file, struct vm_area_struct *vma)
  */
 const struct file_operations nilfs_file_operations = {
        .llseek         = generic_file_llseek,
-       .read           = new_sync_read,
-       .write          = new_sync_write,
        .read_iter      = generic_file_read_iter,
        .write_iter     = generic_file_write_iter,
        .unlocked_ioctl = nilfs_ioctl,
index c1da78dad1afb389039660aa41064bb6f948fa76..840e95e3f1d271b63fc78049f827f459acf989ec 100644 (file)
@@ -2048,10 +2048,8 @@ static int ntfs_file_fsync(struct file *filp, loff_t start, loff_t end,
 
 const struct file_operations ntfs_file_ops = {
        .llseek         = generic_file_llseek,
-       .read           = new_sync_read,
        .read_iter      = generic_file_read_iter,
 #ifdef NTFS_RW
-       .write          = new_sync_write,
        .write_iter     = ntfs_file_write_iter,
        .fsync          = ntfs_file_fsync,
 #endif /* NTFS_RW */
index 91f03ce981087c59bb6d3921c25b74926638746d..8c48e989bebab4af26b8b4f1e84ec3900eae6c50 100644 (file)
@@ -2681,8 +2681,6 @@ const struct inode_operations ocfs2_special_file_iops = {
  */
 const struct file_operations ocfs2_fops = {
        .llseek         = ocfs2_file_llseek,
-       .read           = new_sync_read,
-       .write          = new_sync_write,
        .mmap           = ocfs2_mmap,
        .fsync          = ocfs2_sync_file,
        .release        = ocfs2_file_release,
@@ -2729,8 +2727,6 @@ const struct file_operations ocfs2_dops = {
  */
 const struct file_operations ocfs2_fops_no_plocks = {
        .llseek         = ocfs2_file_llseek,
-       .read           = new_sync_read,
-       .write          = new_sync_write,
        .mmap           = ocfs2_mmap,
        .fsync          = ocfs2_sync_file,
        .release        = ocfs2_file_release,
index 902e88527fcec443244bd12a9a25e1cf895ba763..f993be7f2156fcd863fcc28261add1326efd0146 100644 (file)
@@ -337,8 +337,6 @@ static sector_t omfs_bmap(struct address_space *mapping, sector_t block)
 
 const struct file_operations omfs_file_operations = {
        .llseek = generic_file_llseek,
-       .read = new_sync_read,
-       .write = new_sync_write,
        .read_iter = generic_file_read_iter,
        .write_iter = generic_file_write_iter,
        .mmap = generic_file_mmap,
index 6a83c47d59040df871d2dac261d71fd32bec5587..6796f04d6032ab7e3009d3666bde640fdec37934 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -734,10 +734,10 @@ static int do_dentry_open(struct file *f,
        if ((f->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
                i_readcount_inc(inode);
        if ((f->f_mode & FMODE_READ) &&
-            likely(f->f_op->read || f->f_op->aio_read || f->f_op->read_iter))
+            likely(f->f_op->read || f->f_op->read_iter))
                f->f_mode |= FMODE_CAN_READ;
        if ((f->f_mode & FMODE_WRITE) &&
-            likely(f->f_op->write || f->f_op->aio_write || f->f_op->write_iter))
+            likely(f->f_op->write || f->f_op->write_iter))
                f->f_mode |= FMODE_CAN_WRITE;
 
        f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
index 2d084f2d0b83c698a7df720c35d2fdbeadb65fcb..822da5b7cff06610bec61297ad2a3a688faf11b6 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -946,9 +946,7 @@ err:
 const struct file_operations pipefifo_fops = {
        .open           = fifo_open,
        .llseek         = no_llseek,
-       .read           = new_sync_read,
        .read_iter      = pipe_read,
-       .write          = new_sync_write,
        .write_iter     = pipe_write,
        .poll           = pipe_poll,
        .unlocked_ioctl = pipe_ioctl,
index 4f56de822d2f5995b81006e0bc9783d321b1621d..183a212694bf8af77ee3f682137709ebdb38a274 100644 (file)
@@ -31,9 +31,7 @@
 #include "internal.h"
 
 const struct file_operations ramfs_file_operations = {
-       .read           = new_sync_read,
        .read_iter      = generic_file_read_iter,
-       .write          = new_sync_write,
        .write_iter     = generic_file_write_iter,
        .mmap           = generic_file_mmap,
        .fsync          = noop_fsync,
index f6ab41b39612bd4cd04bd49921095443e54150e3..0b38befa69f356b03b34175f9f629feaf4c8d0fa 100644 (file)
@@ -44,9 +44,7 @@ const struct file_operations ramfs_file_operations = {
        .mmap_capabilities      = ramfs_mmap_capabilities,
        .mmap                   = ramfs_nommu_mmap,
        .get_unmapped_area      = ramfs_nommu_get_unmapped_area,
-       .read                   = new_sync_read,
        .read_iter              = generic_file_read_iter,
-       .write                  = new_sync_write,
        .write_iter             = generic_file_write_iter,
        .fsync                  = noop_fsync,
        .splice_read            = generic_file_splice_read,
index 69128b3786469b807f87763a51c819f4ad076503..45d583c33879e18d89b3fc06d48bbd05a30b6ab3 100644 (file)
 #include <asm/unistd.h>
 
 typedef ssize_t (*io_fn_t)(struct file *, char __user *, size_t, loff_t *);
-typedef ssize_t (*iov_fn_t)(struct kiocb *, const struct iovec *,
-               unsigned long, loff_t);
 typedef ssize_t (*iter_fn_t)(struct kiocb *, struct iov_iter *);
 
 const struct file_operations generic_ro_fops = {
        .llseek         = generic_file_llseek,
-       .read           = new_sync_read,
        .read_iter      = generic_file_read_iter,
        .mmap           = generic_file_readonly_mmap,
        .splice_read    = generic_file_splice_read,
@@ -411,24 +408,7 @@ int rw_verify_area(int read_write, struct file *file, const loff_t *ppos, size_t
        return count > MAX_RW_COUNT ? MAX_RW_COUNT : count;
 }
 
-ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
-{
-       struct iovec iov = { .iov_base = buf, .iov_len = len };
-       struct kiocb kiocb;
-       ssize_t ret;
-
-       init_sync_kiocb(&kiocb, filp);
-       kiocb.ki_pos = *ppos;
-
-       ret = filp->f_op->aio_read(&kiocb, &iov, 1, kiocb.ki_pos);
-       BUG_ON(ret == -EIOCBQUEUED);
-       *ppos = kiocb.ki_pos;
-       return ret;
-}
-
-EXPORT_SYMBOL(do_sync_read);
-
-ssize_t new_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
+static ssize_t new_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
 {
        struct iovec iov = { .iov_base = buf, .iov_len = len };
        struct kiocb kiocb;
@@ -445,24 +425,17 @@ ssize_t new_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *p
        return ret;
 }
 
-EXPORT_SYMBOL(new_sync_read);
-
 ssize_t __vfs_read(struct file *file, char __user *buf, size_t count,
                   loff_t *pos)
 {
-       ssize_t ret;
-
        if (file->f_op->read)
-               ret = file->f_op->read(file, buf, count, pos);
-       else if (file->f_op->aio_read)
-               ret = do_sync_read(file, buf, count, pos);
+               return file->f_op->read(file, buf, count, pos);
        else if (file->f_op->read_iter)
-               ret = new_sync_read(file, buf, count, pos);
+               return new_sync_read(file, buf, count, pos);
        else
-               ret = -EINVAL;
-
-       return ret;
+               return -EINVAL;
 }
+EXPORT_SYMBOL(__vfs_read);
 
 ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
 {
@@ -491,24 +464,7 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
 
 EXPORT_SYMBOL(vfs_read);
 
-ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
-{
-       struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len };
-       struct kiocb kiocb;
-       ssize_t ret;
-
-       init_sync_kiocb(&kiocb, filp);
-       kiocb.ki_pos = *ppos;
-
-       ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos);
-       BUG_ON(ret == -EIOCBQUEUED);
-       *ppos = kiocb.ki_pos;
-       return ret;
-}
-
-EXPORT_SYMBOL(do_sync_write);
-
-ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
+static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
 {
        struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len };
        struct kiocb kiocb;
@@ -525,7 +481,17 @@ ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, lo
        return ret;
 }
 
-EXPORT_SYMBOL(new_sync_write);
+ssize_t __vfs_write(struct file *file, const char __user *p, size_t count,
+                   loff_t *pos)
+{
+       if (file->f_op->write)
+               return file->f_op->write(file, p, count, pos);
+       else if (file->f_op->write_iter)
+               return new_sync_write(file, p, count, pos);
+       else
+               return -EINVAL;
+}
+EXPORT_SYMBOL(__vfs_write);
 
 ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos)
 {
@@ -541,12 +507,7 @@ ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t
        p = (__force const char __user *)buf;
        if (count > MAX_RW_COUNT)
                count =  MAX_RW_COUNT;
-       if (file->f_op->write)
-               ret = file->f_op->write(file, p, count, pos);
-       else if (file->f_op->aio_write)
-               ret = do_sync_write(file, p, count, pos);
-       else
-               ret = new_sync_write(file, p, count, pos);
+       ret = __vfs_write(file, p, count, pos);
        set_fs(old_fs);
        if (ret > 0) {
                fsnotify_modify(file);
@@ -573,12 +534,7 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_
        if (ret >= 0) {
                count = ret;
                file_start_write(file);
-               if (file->f_op->write)
-                       ret = file->f_op->write(file, buf, count, pos);
-               else if (file->f_op->aio_write)
-                       ret = do_sync_write(file, buf, count, pos);
-               else
-                       ret = new_sync_write(file, buf, count, pos);
+               ret = __vfs_write(file, buf, count, pos);
                if (ret > 0) {
                        fsnotify_modify(file);
                        add_wchar(current, ret);
@@ -710,21 +666,6 @@ static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter,
        return ret;
 }
 
-static ssize_t do_sync_readv_writev(struct file *filp, struct iov_iter *iter,
-               loff_t *ppos, iov_fn_t fn)
-{
-       struct kiocb kiocb;
-       ssize_t ret;
-
-       init_sync_kiocb(&kiocb, filp);
-       kiocb.ki_pos = *ppos;
-
-       ret = fn(&kiocb, iter->iov, iter->nr_segs, kiocb.ki_pos);
-       BUG_ON(ret == -EIOCBQUEUED);
-       *ppos = kiocb.ki_pos;
-       return ret;
-}
-
 /* Do it by hand, with file-ops */
 static ssize_t do_loop_readv_writev(struct file *filp, struct iov_iter *iter,
                loff_t *ppos, io_fn_t fn)
@@ -839,7 +780,6 @@ static ssize_t do_readv_writev(int type, struct file *file,
        struct iov_iter iter;
        ssize_t ret;
        io_fn_t fn;
-       iov_fn_t fnv;
        iter_fn_t iter_fn;
 
        ret = import_iovec(type, uvector, nr_segs,
@@ -854,22 +794,17 @@ static ssize_t do_readv_writev(int type, struct file *file,
        if (ret < 0)
                goto out;
 
-       fnv = NULL;
        if (type == READ) {
                fn = file->f_op->read;
-               fnv = file->f_op->aio_read;
                iter_fn = file->f_op->read_iter;
        } else {
                fn = (io_fn_t)file->f_op->write;
-               fnv = file->f_op->aio_write;
                iter_fn = file->f_op->write_iter;
                file_start_write(file);
        }
 
        if (iter_fn)
                ret = do_iter_readv_writev(file, &iter, pos, iter_fn);
-       else if (fnv)
-               ret = do_sync_readv_writev(file, &iter, pos, fnv);
        else
                ret = do_loop_readv_writev(file, &iter, pos, fn);
 
@@ -1019,7 +954,6 @@ static ssize_t compat_do_readv_writev(int type, struct file *file,
        struct iov_iter iter;
        ssize_t ret;
        io_fn_t fn;
-       iov_fn_t fnv;
        iter_fn_t iter_fn;
 
        ret = compat_import_iovec(type, uvector, nr_segs,
@@ -1034,22 +968,17 @@ static ssize_t compat_do_readv_writev(int type, struct file *file,
        if (ret < 0)
                goto out;
 
-       fnv = NULL;
        if (type == READ) {
                fn = file->f_op->read;
-               fnv = file->f_op->aio_read;
                iter_fn = file->f_op->read_iter;
        } else {
                fn = (io_fn_t)file->f_op->write;
-               fnv = file->f_op->aio_write;
                iter_fn = file->f_op->write_iter;
                file_start_write(file);
        }
 
        if (iter_fn)
                ret = do_iter_readv_writev(file, &iter, pos, iter_fn);
-       else if (fnv)
-               ret = do_sync_readv_writev(file, &iter, pos, fnv);
        else
                ret = do_loop_readv_writev(file, &iter, pos, fn);
 
index 751dd3f4346b5dab98d7b4861cd24a617c148bae..96a1bcf33db4435098baa153f807a71274543aaf 100644 (file)
@@ -243,8 +243,6 @@ drop_write_lock:
 }
 
 const struct file_operations reiserfs_file_operations = {
-       .read = new_sync_read,
-       .write = new_sync_write,
        .unlocked_ioctl = reiserfs_ioctl,
 #ifdef CONFIG_COMPAT
        .compat_ioctl = reiserfs_compat_ioctl,
index 7da9e2153953eb31399bf3909a9ef881328ddf90..1118a0dc6b45f0292cfdf34970d35c6dfc2e6ba8 100644 (file)
@@ -81,7 +81,6 @@ static unsigned romfs_mmap_capabilities(struct file *file)
 
 const struct file_operations romfs_ro_fops = {
        .llseek                 = generic_file_llseek,
-       .read                   = new_sync_read,
        .read_iter              = generic_file_read_iter,
        .splice_read            = generic_file_splice_read,
        .mmap                   = romfs_mmap,
index b00811c75b24f63acb1651991f6972f4b0b6ff54..a48e30410ad1979eaf1068cd59ddfa2dcc89c69a 100644 (file)
@@ -21,9 +21,7 @@
  */
 const struct file_operations sysv_file_operations = {
        .llseek         = generic_file_llseek,
-       .read           = new_sync_read,
        .read_iter      = generic_file_read_iter,
-       .write          = new_sync_write,
        .write_iter     = generic_file_write_iter,
        .mmap           = generic_file_mmap,
        .fsync          = generic_file_fsync,
index c3d15fe834033d4d080ea408dbbb961f1e4719c6..475b15635f11654f40ddbc23dfc0f76aeb2a1099 100644 (file)
@@ -1580,8 +1580,6 @@ const struct inode_operations ubifs_symlink_inode_operations = {
 
 const struct file_operations ubifs_file_operations = {
        .llseek         = generic_file_llseek,
-       .read           = new_sync_read,
-       .write          = new_sync_write,
        .read_iter      = generic_file_read_iter,
        .write_iter     = ubifs_write_iter,
        .mmap           = ubifs_file_mmap,
index 7f885cc8b0b798dca3239a9f72f87741fd8b023f..74050bff64f4000b745374fccde9a9e3eaec4256 100644 (file)
@@ -240,12 +240,10 @@ static int udf_release_file(struct inode *inode, struct file *filp)
 }
 
 const struct file_operations udf_file_operations = {
-       .read                   = new_sync_read,
        .read_iter              = generic_file_read_iter,
        .unlocked_ioctl         = udf_ioctl,
        .open                   = generic_file_open,
        .mmap                   = generic_file_mmap,
-       .write                  = new_sync_write,
        .write_iter             = udf_file_write_iter,
        .release                = udf_release_file,
        .fsync                  = generic_file_fsync,
index c84ec010a6761ff683e732973bd8780d989e6531..042ddbf110ccf65254c82bcb834c63916c941d81 100644 (file)
@@ -35,9 +35,7 @@
  
 const struct file_operations ufs_file_operations = {
        .llseek         = generic_file_llseek,
-       .read           = new_sync_read,
        .read_iter      = generic_file_read_iter,
-       .write          = new_sync_write,
        .write_iter     = generic_file_write_iter,
        .mmap           = generic_file_mmap,
        .open           = generic_file_open,
index f44212fae65327347db1ba9f8ec1739d30650f44..44856c3b9617c6f658f6ab9b05b5f08be23f2a01 100644 (file)
@@ -1386,8 +1386,6 @@ xfs_file_llseek(
 
 const struct file_operations xfs_file_operations = {
        .llseek         = xfs_file_llseek,
-       .read           = new_sync_read,
-       .write          = new_sync_write,
        .read_iter      = xfs_file_read_iter,
        .write_iter     = xfs_file_write_iter,
        .splice_read    = xfs_file_splice_read,
index d502e5436c847530e7a7acd476cc85bd24434edf..4d9acc91de12c24f3f0308a1aefea6888ca0648c 100644 (file)
@@ -1562,8 +1562,6 @@ struct file_operations {
        loff_t (*llseek) (struct file *, loff_t, int);
        ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
        ssize_t (*write) (struct file *, 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);
        ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
        ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
        int (*iterate) (struct file *, struct dir_context *);
@@ -1639,6 +1637,7 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
                              struct iovec **ret_pointer);
 
 extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *);
+extern ssize_t __vfs_write(struct file *, const char __user *, size_t, loff_t *);
 extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *);
 extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *);
 extern ssize_t vfs_readv(struct file *, const struct iovec __user *,
@@ -2573,10 +2572,6 @@ extern ssize_t __generic_file_write_iter(struct kiocb *, struct iov_iter *);
 extern ssize_t generic_file_write_iter(struct kiocb *, struct iov_iter *);
 extern ssize_t generic_file_direct_write(struct kiocb *, struct iov_iter *, loff_t);
 extern ssize_t generic_perform_write(struct file *, struct iov_iter *, loff_t);
-extern ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos);
-extern ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos);
-extern ssize_t new_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos);
-extern ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos);
 
 ssize_t vfs_iter_read(struct file *file, struct iov_iter *iter, loff_t *ppos);
 ssize_t vfs_iter_write(struct file *file, struct iov_iter *iter, loff_t *ppos);
index 6fab66c5c5af6356318e52c92703bdb3ea37a3d4..c6b97e58cf8455c120c486192e9d38eb9834343a 100644 (file)
@@ -211,6 +211,8 @@ struct p9_dirent {
        char d_name[256];
 };
 
+struct iov_iter;
+
 int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb);
 int p9_client_rename(struct p9_fid *fid, struct p9_fid *newdirfid,
                     const char *name);
@@ -236,10 +238,8 @@ int p9_client_clunk(struct p9_fid *fid);
 int p9_client_fsync(struct p9_fid *fid, int datasync);
 int p9_client_remove(struct p9_fid *fid);
 int p9_client_unlinkat(struct p9_fid *dfid, const char *name, int flags);
-int p9_client_read(struct p9_fid *fid, char *data, char __user *udata,
-                                                       u64 offset, u32 count);
-int p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
-                                                       u64 offset, u32 count);
+int p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err);
+int p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err);
 int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset);
 int p9dirent_read(struct p9_client *clnt, char *buf, int len,
                  struct p9_dirent *dirent);
index 2a25dec3021166d5aba52ad155e8ca01e0b1570e..5122b5e40f78f1aec1b30aa17d13dd68558d9f4f 100644 (file)
@@ -61,7 +61,7 @@ struct p9_trans_module {
        int (*cancel) (struct p9_client *, struct p9_req_t *req);
        int (*cancelled)(struct p9_client *, struct p9_req_t *req);
        int (*zc_request)(struct p9_client *, struct p9_req_t *,
-                         char *, char *, int , int, int, int);
+                         struct iov_iter *, struct iov_iter *, int , int, int);
 };
 
 void v9fs_register_trans(struct p9_trans_module *m);
index e6c10d1a405821d55b7595a2cd5e3404766d3d42..74963d192c5d96ce3674f0adbf554c95af4867ec 100644 (file)
@@ -213,7 +213,7 @@ static int acct_on(struct filename *pathname)
                return -EACCES;
        }
 
-       if (!file->f_op->write) {
+       if (!(file->f_mode & FMODE_CAN_WRITE)) {
                kfree(acct);
                filp_close(file, NULL);
                return -EIO;
index 3fba2dc97c44bece0d6fb5754afdafb1dba6353e..e544508e2a4bc3e3dfa6190abdd3faf0616c95f2 100644 (file)
@@ -1016,7 +1016,7 @@ static int validate_mmap_request(struct file *file,
                 * device */
                if (!file->f_op->get_unmapped_area)
                        capabilities &= ~NOMMU_MAP_DIRECT;
-               if (!file->f_op->read)
+               if (!(file->f_mode & FMODE_CAN_READ))
                        capabilities &= ~NOMMU_MAP_COPY;
 
                /* The file shall have been opened with read permission. */
@@ -1240,7 +1240,7 @@ static int do_mmap_private(struct vm_area_struct *vma,
 
                old_fs = get_fs();
                set_fs(KERNEL_DS);
-               ret = vma->vm_file->f_op->read(vma->vm_file, base, len, &fpos);
+               ret = __vfs_read(vma->vm_file, base, len, &fpos);
                set_fs(old_fs);
 
                if (ret < 0)
index 80b360c7bcd1696a77cf74f44b334ce53d367688..1ea2400b52450fccdc526d569d1447657379609d 100644 (file)
@@ -3118,8 +3118,6 @@ static const struct file_operations shmem_file_operations = {
        .mmap           = shmem_mmap,
 #ifdef CONFIG_TMPFS
        .llseek         = shmem_file_llseek,
-       .read           = new_sync_read,
-       .write          = new_sync_write,
        .read_iter      = shmem_file_read_iter,
        .write_iter     = generic_file_write_iter,
        .fsync          = noop_fsync,
index e86a9bea1d160ccc1a739eee576d0bdbf0483956..6f4c4c88db84ecb084ca5553113d9ad2963e4985 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/uaccess.h>
+#include <linux/uio.h>
 #include <net/9p/9p.h>
 #include <linux/parser.h>
 #include <net/9p/client.h>
@@ -555,7 +556,7 @@ out_err:
  */
 
 static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
-                             char *uidata, int in_hdrlen, int kern_buf)
+                             struct iov_iter *uidata, int in_hdrlen)
 {
        int err;
        int ecode;
@@ -591,16 +592,11 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
                ename = &req->rc->sdata[req->rc->offset];
                if (len > inline_len) {
                        /* We have error in external buffer */
-                       if (kern_buf) {
-                               memcpy(ename + inline_len, uidata,
-                                      len - inline_len);
-                       } else {
-                               err = copy_from_user(ename + inline_len,
-                                                    uidata, len - inline_len);
-                               if (err) {
-                                       err = -EFAULT;
-                                       goto out_err;
-                               }
+                       err = copy_from_iter(ename + inline_len,
+                                            len - inline_len, uidata);
+                       if (err != len - inline_len) {
+                               err = -EFAULT;
+                               goto out_err;
                        }
                }
                ename = NULL;
@@ -806,8 +802,8 @@ reterr:
  * p9_client_zc_rpc - issue a request and wait for a response
  * @c: client session
  * @type: type of request
- * @uidata: user bffer that should be ued for zero copy read
- * @uodata: user buffer that shoud be user for zero copy write
+ * @uidata: destination for zero copy read
+ * @uodata: source for zero copy write
  * @inlen: read buffer size
  * @olen: write buffer size
  * @hdrlen: reader header size, This is the size of response protocol data
@@ -816,9 +812,10 @@ reterr:
  * Returns request structure (which client must free using p9_free_req)
  */
 static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
-                                        char *uidata, char *uodata,
+                                        struct iov_iter *uidata,
+                                        struct iov_iter *uodata,
                                         int inlen, int olen, int in_hdrlen,
-                                        int kern_buf, const char *fmt, ...)
+                                        const char *fmt, ...)
 {
        va_list ap;
        int sigpending, err;
@@ -841,12 +838,8 @@ static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
        } else
                sigpending = 0;
 
-       /* If we are called with KERNEL_DS force kern_buf */
-       if (segment_eq(get_fs(), KERNEL_DS))
-               kern_buf = 1;
-
        err = c->trans_mod->zc_request(c, req, uidata, uodata,
-                                      inlen, olen, in_hdrlen, kern_buf);
+                                      inlen, olen, in_hdrlen);
        if (err < 0) {
                if (err == -EIO)
                        c->status = Disconnected;
@@ -876,7 +869,7 @@ static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
        if (err < 0)
                goto reterr;
 
-       err = p9_check_zc_errors(c, req, uidata, in_hdrlen, kern_buf);
+       err = p9_check_zc_errors(c, req, uidata, in_hdrlen);
        trace_9p_client_res(c, type, req->rc->tag, err);
        if (!err)
                return req;
@@ -1123,6 +1116,7 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
                fid = NULL;
                goto error;
        }
+       fid->uid = n_uname;
 
        req = p9_client_rpc(clnt, P9_TATTACH, "ddss?u", fid->fid,
                        afid ? afid->fid : P9_NOFID, uname, aname, n_uname);
@@ -1541,142 +1535,128 @@ error:
 EXPORT_SYMBOL(p9_client_unlinkat);
 
 int
-p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
-                                                               u32 count)
+p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err)
 {
-       char *dataptr;
-       int kernel_buf = 0;
+       struct p9_client *clnt = fid->clnt;
        struct p9_req_t *req;
-       struct p9_client *clnt;
-       int err, rsize, non_zc = 0;
-
+       int total = 0;
 
        p9_debug(P9_DEBUG_9P, ">>> TREAD fid %d offset %llu %d\n",
-                  fid->fid, (unsigned long long) offset, count);
-       err = 0;
-       clnt = fid->clnt;
-
-       rsize = fid->iounit;
-       if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
-               rsize = clnt->msize - P9_IOHDRSZ;
-
-       if (count < rsize)
-               rsize = count;
-
-       /* Don't bother zerocopy for small IO (< 1024) */
-       if (clnt->trans_mod->zc_request && rsize > 1024) {
-               char *indata;
-               if (data) {
-                       kernel_buf = 1;
-                       indata = data;
-               } else
-                       indata = (__force char *)udata;
-               /*
-                * response header len is 11
-                * PDU Header(7) + IO Size (4)
-                */
-               req = p9_client_zc_rpc(clnt, P9_TREAD, indata, NULL, rsize, 0,
-                                      11, kernel_buf, "dqd", fid->fid,
-                                      offset, rsize);
-       } else {
-               non_zc = 1;
-               req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset,
-                                   rsize);
-       }
-       if (IS_ERR(req)) {
-               err = PTR_ERR(req);
-               goto error;
-       }
+                  fid->fid, (unsigned long long) offset, (int)iov_iter_count(to));
+
+       while (iov_iter_count(to)) {
+               int count = iov_iter_count(to);
+               int rsize, non_zc = 0;
+               char *dataptr;
+                       
+               rsize = fid->iounit;
+               if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
+                       rsize = clnt->msize - P9_IOHDRSZ;
+
+               if (count < rsize)
+                       rsize = count;
+
+               /* Don't bother zerocopy for small IO (< 1024) */
+               if (clnt->trans_mod->zc_request && rsize > 1024) {
+                       /*
+                        * response header len is 11
+                        * PDU Header(7) + IO Size (4)
+                        */
+                       req = p9_client_zc_rpc(clnt, P9_TREAD, to, NULL, rsize,
+                                              0, 11, "dqd", fid->fid,
+                                              offset, rsize);
+               } else {
+                       non_zc = 1;
+                       req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset,
+                                           rsize);
+               }
+               if (IS_ERR(req)) {
+                       *err = PTR_ERR(req);
+                       break;
+               }
 
-       err = p9pdu_readf(req->rc, clnt->proto_version, "D", &count, &dataptr);
-       if (err) {
-               trace_9p_protocol_dump(clnt, req->rc);
-               goto free_and_error;
-       }
+               *err = p9pdu_readf(req->rc, clnt->proto_version,
+                                  "D", &count, &dataptr);
+               if (*err) {
+                       trace_9p_protocol_dump(clnt, req->rc);
+                       p9_free_req(clnt, req);
+                       break;
+               }
 
-       p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", count);
+               p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", count);
+               if (!count) {
+                       p9_free_req(clnt, req);
+                       break;
+               }
 
-       if (non_zc) {
-               if (data) {
-                       memmove(data, dataptr, count);
-               } else {
-                       err = copy_to_user(udata, dataptr, count);
-                       if (err) {
-                               err = -EFAULT;
-                               goto free_and_error;
+               if (non_zc) {
+                       int n = copy_to_iter(dataptr, count, to);
+                       total += n;
+                       offset += n;
+                       if (n != count) {
+                               *err = -EFAULT;
+                               p9_free_req(clnt, req);
+                               break;
                        }
+               } else {
+                       iov_iter_advance(to, count);
+                       total += count;
+                       offset += count;
                }
+               p9_free_req(clnt, req);
        }
-       p9_free_req(clnt, req);
-       return count;
-
-free_and_error:
-       p9_free_req(clnt, req);
-error:
-       return err;
+       return total;
 }
 EXPORT_SYMBOL(p9_client_read);
 
 int
-p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
-                                                       u64 offset, u32 count)
+p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err)
 {
-       int err, rsize;
-       int kernel_buf = 0;
-       struct p9_client *clnt;
+       struct p9_client *clnt = fid->clnt;
        struct p9_req_t *req;
+       int total = 0;
+
+       p9_debug(P9_DEBUG_9P, ">>> TWRITE fid %d offset %llu count %zd\n",
+                               fid->fid, (unsigned long long) offset,
+                               iov_iter_count(from));
+
+       while (iov_iter_count(from)) {
+               int count = iov_iter_count(from);
+               int rsize = fid->iounit;
+               if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
+                       rsize = clnt->msize - P9_IOHDRSZ;
+
+               if (count < rsize)
+                       rsize = count;
+
+               /* Don't bother zerocopy for small IO (< 1024) */
+               if (clnt->trans_mod->zc_request && rsize > 1024) {
+                       req = p9_client_zc_rpc(clnt, P9_TWRITE, NULL, from, 0,
+                                              rsize, P9_ZC_HDR_SZ, "dqd",
+                                              fid->fid, offset, rsize);
+               } else {
+                       req = p9_client_rpc(clnt, P9_TWRITE, "dqV", fid->fid,
+                                                   offset, rsize, from);
+               }
+               if (IS_ERR(req)) {
+                       *err = PTR_ERR(req);
+                       break;
+               }
 
-       p9_debug(P9_DEBUG_9P, ">>> TWRITE fid %d offset %llu count %d\n",
-                               fid->fid, (unsigned long long) offset, count);
-       err = 0;
-       clnt = fid->clnt;
-
-       rsize = fid->iounit;
-       if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
-               rsize = clnt->msize - P9_IOHDRSZ;
+               *err = p9pdu_readf(req->rc, clnt->proto_version, "d", &count);
+               if (*err) {
+                       trace_9p_protocol_dump(clnt, req->rc);
+                       p9_free_req(clnt, req);
+               }
 
-       if (count < rsize)
-               rsize = count;
+               p9_debug(P9_DEBUG_9P, "<<< RWRITE count %d\n", count);
 
-       /* Don't bother zerocopy for small IO (< 1024) */
-       if (clnt->trans_mod->zc_request && rsize > 1024) {
-               char *odata;
-               if (data) {
-                       kernel_buf = 1;
-                       odata = data;
-               } else
-                       odata = (char *)udata;
-               req = p9_client_zc_rpc(clnt, P9_TWRITE, NULL, odata, 0, rsize,
-                                      P9_ZC_HDR_SZ, kernel_buf, "dqd",
-                                      fid->fid, offset, rsize);
-       } else {
-               if (data)
-                       req = p9_client_rpc(clnt, P9_TWRITE, "dqD", fid->fid,
-                                           offset, rsize, data);
-               else
-                       req = p9_client_rpc(clnt, P9_TWRITE, "dqU", fid->fid,
-                                           offset, rsize, udata);
-       }
-       if (IS_ERR(req)) {
-               err = PTR_ERR(req);
-               goto error;
-       }
-
-       err = p9pdu_readf(req->rc, clnt->proto_version, "d", &count);
-       if (err) {
-               trace_9p_protocol_dump(clnt, req->rc);
-               goto free_and_error;
+               p9_free_req(clnt, req);
+               iov_iter_advance(from, count);
+               total += count;
+               offset += count;
        }
-
-       p9_debug(P9_DEBUG_9P, "<<< RWRITE count %d\n", count);
-
-       p9_free_req(clnt, req);
-       return count;
-
-free_and_error:
-       p9_free_req(clnt, req);
-error:
-       return err;
+       return total;
 }
 EXPORT_SYMBOL(p9_client_write);
 
@@ -2068,6 +2048,10 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
        struct p9_client *clnt;
        struct p9_req_t *req;
        char *dataptr;
+       struct kvec kv = {.iov_base = data, .iov_len = count};
+       struct iov_iter to;
+
+       iov_iter_kvec(&to, READ | ITER_KVEC, &kv, 1, count);
 
        p9_debug(P9_DEBUG_9P, ">>> TREADDIR fid %d offset %llu count %d\n",
                                fid->fid, (unsigned long long) offset, count);
@@ -2088,8 +2072,8 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
                 * response header len is 11
                 * PDU Header(7) + IO Size (4)
                 */
-               req = p9_client_zc_rpc(clnt, P9_TREADDIR, data, NULL, rsize, 0,
-                                      11, 1, "dqd", fid->fid, offset, rsize);
+               req = p9_client_zc_rpc(clnt, P9_TREADDIR, &to, NULL, rsize, 0,
+                                      11, "dqd", fid->fid, offset, rsize);
        } else {
                non_zc = 1;
                req = p9_client_rpc(clnt, P9_TREADDIR, "dqd", fid->fid,
index ab9127ec5b7a6881e7dd2116e49819186675562f..e9d0f0c1a04827f0d1cc0f554f6b4dfaabb2c414 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/sched.h>
 #include <linux/stddef.h>
 #include <linux/types.h>
+#include <linux/uio.h>
 #include <net/9p/9p.h>
 #include <net/9p/client.h>
 #include "protocol.h"
@@ -69,10 +70,11 @@ static size_t pdu_write(struct p9_fcall *pdu, const void *data, size_t size)
 }
 
 static size_t
-pdu_write_u(struct p9_fcall *pdu, const char __user *udata, size_t size)
+pdu_write_u(struct p9_fcall *pdu, struct iov_iter *from, size_t size)
 {
        size_t len = min(pdu->capacity - pdu->size, size);
-       if (copy_from_user(&pdu->sdata[pdu->size], udata, len))
+       struct iov_iter i = *from;
+       if (copy_from_iter(&pdu->sdata[pdu->size], len, &i) != len)
                len = 0;
 
        pdu->size += len;
@@ -437,23 +439,13 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
                                                 stbuf->extension, stbuf->n_uid,
                                                 stbuf->n_gid, stbuf->n_muid);
                        } break;
-               case 'D':{
-                               uint32_t count = va_arg(ap, uint32_t);
-                               const void *data = va_arg(ap, const void *);
-
-                               errcode = p9pdu_writef(pdu, proto_version, "d",
-                                                                       count);
-                               if (!errcode && pdu_write(pdu, data, count))
-                                       errcode = -EFAULT;
-                       }
-                       break;
-               case 'U':{
+               case 'V':{
                                int32_t count = va_arg(ap, int32_t);
-                               const char __user *udata =
-                                               va_arg(ap, const void __user *);
+                               struct iov_iter *from =
+                                               va_arg(ap, struct iov_iter *);
                                errcode = p9pdu_writef(pdu, proto_version, "d",
                                                                        count);
-                               if (!errcode && pdu_write_u(pdu, udata, count))
+                               if (!errcode && pdu_write_u(pdu, from, count))
                                        errcode = -EFAULT;
                        }
                        break;
index 2ee3879161b1769f456501044a08c8ebfda420a0..38aa6345bdfa2ec9fc52155e5b0eb3b369fdf463 100644 (file)
  *
  */
 
-#include <linux/slab.h>
+#include <linux/mm.h>
 #include <linux/module.h>
-#include <net/9p/9p.h>
-#include <net/9p/client.h>
-#include <linux/scatterlist.h>
-#include "trans_common.h"
 
 /**
  *  p9_release_req_pages - Release pages after the transaction.
@@ -31,39 +27,3 @@ void p9_release_pages(struct page **pages, int nr_pages)
                        put_page(pages[i]);
 }
 EXPORT_SYMBOL(p9_release_pages);
-
-/**
- * p9_nr_pages - Return number of pages needed to accommodate the payload.
- */
-int p9_nr_pages(char *data, int len)
-{
-       unsigned long start_page, end_page;
-       start_page =  (unsigned long)data >> PAGE_SHIFT;
-       end_page = ((unsigned long)data + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
-       return end_page - start_page;
-}
-EXPORT_SYMBOL(p9_nr_pages);
-
-/**
- * payload_gup - Translates user buffer into kernel pages and
- * pins them either for read/write through get_user_pages_fast().
- * @req: Request to be sent to server.
- * @pdata_off: data offset into the first page after translation (gup).
- * @pdata_len: Total length of the IO. gup may not return requested # of pages.
- * @nr_pages: number of pages to accommodate the payload
- * @rw: Indicates if the pages are for read or write.
- */
-
-int p9_payload_gup(char *data, int *nr_pages, struct page **pages, int write)
-{
-       int nr_mapped_pages;
-
-       nr_mapped_pages = get_user_pages_fast((unsigned long)data,
-                                             *nr_pages, write, pages);
-       if (nr_mapped_pages <= 0)
-               return nr_mapped_pages;
-
-       *nr_pages = nr_mapped_pages;
-       return 0;
-}
-EXPORT_SYMBOL(p9_payload_gup);
index 173bb550a9eb163df30c3b46b8770d0a37c84aa3..c43babb3f6354ea15bdf125352b6de83fb670af1 100644 (file)
@@ -13,5 +13,3 @@
  */
 
 void p9_release_pages(struct page **, int);
-int p9_payload_gup(char *, int *, struct page **, int);
-int p9_nr_pages(char *, int);
index 36a1a739ad68ff57eace5ba4bc4166faf12c485b..e62bcbbabb5e3cd43717f7980fce3e280aba3ded 100644 (file)
@@ -217,15 +217,15 @@ static int p9_virtio_cancel(struct p9_client *client, struct p9_req_t *req)
  * @start: which segment of the sg_list to start at
  * @pdata: a list of pages to add into sg.
  * @nr_pages: number of pages to pack into the scatter/gather list
- * @data: data to pack into scatter/gather list
+ * @offs: amount of data in the beginning of first page _not_ to pack
  * @count: amount of data to pack into the scatter/gather list
  */
 static int
 pack_sg_list_p(struct scatterlist *sg, int start, int limit,
-              struct page **pdata, int nr_pages, char *data, int count)
+              struct page **pdata, int nr_pages, size_t offs, int count)
 {
        int i = 0, s;
-       int data_off;
+       int data_off = offs;
        int index = start;
 
        BUG_ON(nr_pages > (limit - start));
@@ -233,16 +233,14 @@ pack_sg_list_p(struct scatterlist *sg, int start, int limit,
         * if the first page doesn't start at
         * page boundary find the offset
         */
-       data_off = offset_in_page(data);
        while (nr_pages) {
-               s = rest_of_page(data);
+               s = PAGE_SIZE - data_off;
                if (s > count)
                        s = count;
                /* Make sure we don't terminate early. */
                sg_unmark_end(&sg[index]);
                sg_set_page(&sg[index++], pdata[i++], s, data_off);
                data_off = 0;
-               data += s;
                count -= s;
                nr_pages--;
        }
@@ -314,11 +312,20 @@ req_retry:
 }
 
 static int p9_get_mapped_pages(struct virtio_chan *chan,
-                              struct page **pages, char *data,
-                              int nr_pages, int write, int kern_buf)
+                              struct page ***pages,
+                              struct iov_iter *data,
+                              int count,
+                              size_t *offs,
+                              int *need_drop)
 {
+       int nr_pages;
        int err;
-       if (!kern_buf) {
+
+       if (!iov_iter_count(data))
+               return 0;
+
+       if (!(data->type & ITER_KVEC)) {
+               int n;
                /*
                 * We allow only p9_max_pages pinned. We wait for the
                 * Other zc request to finish here
@@ -329,26 +336,49 @@ static int p9_get_mapped_pages(struct virtio_chan *chan,
                        if (err == -ERESTARTSYS)
                                return err;
                }
-               err = p9_payload_gup(data, &nr_pages, pages, write);
-               if (err < 0)
-                       return err;
+               n = iov_iter_get_pages_alloc(data, pages, count, offs);
+               if (n < 0)
+                       return n;
+               *need_drop = 1;
+               nr_pages = DIV_ROUND_UP(n + *offs, PAGE_SIZE);
                atomic_add(nr_pages, &vp_pinned);
+               return n;
        } else {
                /* kernel buffer, no need to pin pages */
-               int s, index = 0;
-               int count = nr_pages;
-               while (nr_pages) {
-                       s = rest_of_page(data);
-                       if (is_vmalloc_addr(data))
-                               pages[index++] = vmalloc_to_page(data);
+               int index;
+               size_t len;
+               void *p;
+
+               /* we'd already checked that it's non-empty */
+               while (1) {
+                       len = iov_iter_single_seg_count(data);
+                       if (likely(len)) {
+                               p = data->kvec->iov_base + data->iov_offset;
+                               break;
+                       }
+                       iov_iter_advance(data, 0);
+               }
+               if (len > count)
+                       len = count;
+
+               nr_pages = DIV_ROUND_UP((unsigned long)p + len, PAGE_SIZE) -
+                          (unsigned long)p / PAGE_SIZE;
+
+               *pages = kmalloc(sizeof(struct page *) * nr_pages, GFP_NOFS);
+               if (!*pages)
+                       return -ENOMEM;
+
+               *need_drop = 0;
+               p -= (*offs = (unsigned long)p % PAGE_SIZE);
+               for (index = 0; index < nr_pages; index++) {
+                       if (is_vmalloc_addr(p))
+                               (*pages)[index] = vmalloc_to_page(p);
                        else
-                               pages[index++] = kmap_to_page(data);
-                       data += s;
-                       nr_pages--;
+                               (*pages)[index] = kmap_to_page(p);
+                       p += PAGE_SIZE;
                }
-               nr_pages = count;
+               return len;
        }
-       return nr_pages;
 }
 
 /**
@@ -364,8 +394,8 @@ static int p9_get_mapped_pages(struct virtio_chan *chan,
  */
 static int
 p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req,
-                    char *uidata, char *uodata, int inlen,
-                    int outlen, int in_hdr_len, int kern_buf)
+                    struct iov_iter *uidata, struct iov_iter *uodata,
+                    int inlen, int outlen, int in_hdr_len)
 {
        int in, out, err, out_sgs, in_sgs;
        unsigned long flags;
@@ -373,41 +403,32 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req,
        struct page **in_pages = NULL, **out_pages = NULL;
        struct virtio_chan *chan = client->trans;
        struct scatterlist *sgs[4];
+       size_t offs;
+       int need_drop = 0;
 
        p9_debug(P9_DEBUG_TRANS, "virtio request\n");
 
        if (uodata) {
-               out_nr_pages = p9_nr_pages(uodata, outlen);
-               out_pages = kmalloc(sizeof(struct page *) * out_nr_pages,
-                                   GFP_NOFS);
-               if (!out_pages) {
-                       err = -ENOMEM;
-                       goto err_out;
-               }
-               out_nr_pages = p9_get_mapped_pages(chan, out_pages, uodata,
-                                                  out_nr_pages, 0, kern_buf);
-               if (out_nr_pages < 0) {
-                       err = out_nr_pages;
-                       kfree(out_pages);
-                       out_pages = NULL;
-                       goto err_out;
+               int n = p9_get_mapped_pages(chan, &out_pages, uodata,
+                                           outlen, &offs, &need_drop);
+               if (n < 0)
+                       return n;
+               out_nr_pages = DIV_ROUND_UP(n + offs, PAGE_SIZE);
+               if (n != outlen) {
+                       __le32 v = cpu_to_le32(n);
+                       memcpy(&req->tc->sdata[req->tc->size - 4], &v, 4);
+                       outlen = n;
                }
-       }
-       if (uidata) {
-               in_nr_pages = p9_nr_pages(uidata, inlen);
-               in_pages = kmalloc(sizeof(struct page *) * in_nr_pages,
-                                  GFP_NOFS);
-               if (!in_pages) {
-                       err = -ENOMEM;
-                       goto err_out;
-               }
-               in_nr_pages = p9_get_mapped_pages(chan, in_pages, uidata,
-                                                 in_nr_pages, 1, kern_buf);
-               if (in_nr_pages < 0) {
-                       err = in_nr_pages;
-                       kfree(in_pages);
-                       in_pages = NULL;
-                       goto err_out;
+       } else if (uidata) {
+               int n = p9_get_mapped_pages(chan, &in_pages, uidata,
+                                           inlen, &offs, &need_drop);
+               if (n < 0)
+                       return n;
+               in_nr_pages = DIV_ROUND_UP(n + offs, PAGE_SIZE);
+               if (n != inlen) {
+                       __le32 v = cpu_to_le32(n);
+                       memcpy(&req->tc->sdata[req->tc->size - 4], &v, 4);
+                       inlen = n;
                }
        }
        req->status = REQ_STATUS_SENT;
@@ -426,7 +447,7 @@ req_retry_pinned:
        if (out_pages) {
                sgs[out_sgs++] = chan->sg + out;
                out += pack_sg_list_p(chan->sg, out, VIRTQUEUE_NUM,
-                                     out_pages, out_nr_pages, uodata, outlen);
+                                     out_pages, out_nr_pages, offs, outlen);
        }
                
        /*
@@ -444,7 +465,7 @@ req_retry_pinned:
        if (in_pages) {
                sgs[out_sgs + in_sgs++] = chan->sg + out + in;
                in += pack_sg_list_p(chan->sg, out + in, VIRTQUEUE_NUM,
-                                    in_pages, in_nr_pages, uidata, inlen);
+                                    in_pages, in_nr_pages, offs, inlen);
        }
 
        BUG_ON(out_sgs + in_sgs > ARRAY_SIZE(sgs));
@@ -478,7 +499,7 @@ req_retry_pinned:
         * Non kernel buffers are pinned, unpin them
         */
 err_out:
-       if (!kern_buf) {
+       if (need_drop) {
                if (in_pages) {
                        p9_release_pages(in_pages, in_nr_pages);
                        atomic_sub(in_nr_pages, &vp_pinned);
index 5b0126234606dac94152b69fb42a571b1f3cc7bf..3e33959f3ce5711863fca7ce1805a4d1cf4ed6e0 100644 (file)
@@ -140,8 +140,6 @@ static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
 static const struct file_operations socket_file_ops = {
        .owner =        THIS_MODULE,
        .llseek =       no_llseek,
-       .read =         new_sync_read,
-       .write =        new_sync_write,
        .read_iter =    sock_read_iter,
        .write_iter =   sock_write_iter,
        .poll =         sock_poll,
index a69ebc79bc5008e8251c8837a5ea973eb2c458b9..8e43610ec9b56a866057c203d563895e582558f9 100644 (file)
@@ -3033,9 +3033,7 @@ static ssize_t snd_pcm_write(struct file *file, const char __user *buf,
        return result;
 }
 
-static ssize_t snd_pcm_aio_read(struct kiocb *iocb, const struct iovec *iov,
-                            unsigned long nr_segs, loff_t pos)
-
+static ssize_t snd_pcm_readv(struct kiocb *iocb, struct iov_iter *to)
 {
        struct snd_pcm_file *pcm_file;
        struct snd_pcm_substream *substream;
@@ -3052,16 +3050,18 @@ static ssize_t snd_pcm_aio_read(struct kiocb *iocb, const struct iovec *iov,
        runtime = substream->runtime;
        if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
                return -EBADFD;
-       if (nr_segs > 1024 || nr_segs != runtime->channels)
+       if (!iter_is_iovec(to))
+               return -EINVAL;
+       if (to->nr_segs > 1024 || to->nr_segs != runtime->channels)
                return -EINVAL;
-       if (!frame_aligned(runtime, iov->iov_len))
+       if (!frame_aligned(runtime, to->iov->iov_len))
                return -EINVAL;
-       frames = bytes_to_samples(runtime, iov->iov_len);
-       bufs = kmalloc(sizeof(void *) * nr_segs, GFP_KERNEL);
+       frames = bytes_to_samples(runtime, to->iov->iov_len);
+       bufs = kmalloc(sizeof(void *) * to->nr_segs, GFP_KERNEL);
        if (bufs == NULL)
                return -ENOMEM;
-       for (i = 0; i < nr_segs; ++i)
-               bufs[i] = iov[i].iov_base;
+       for (i = 0; i < to->nr_segs; ++i)
+               bufs[i] = to->iov[i].iov_base;
        result = snd_pcm_lib_readv(substream, bufs, frames);
        if (result > 0)
                result = frames_to_bytes(runtime, result);
@@ -3069,8 +3069,7 @@ static ssize_t snd_pcm_aio_read(struct kiocb *iocb, const struct iovec *iov,
        return result;
 }
 
-static ssize_t snd_pcm_aio_write(struct kiocb *iocb, const struct iovec *iov,
-                             unsigned long nr_segs, loff_t pos)
+static ssize_t snd_pcm_writev(struct kiocb *iocb, struct iov_iter *from)
 {
        struct snd_pcm_file *pcm_file;
        struct snd_pcm_substream *substream;
@@ -3087,15 +3086,17 @@ static ssize_t snd_pcm_aio_write(struct kiocb *iocb, const struct iovec *iov,
        runtime = substream->runtime;
        if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
                return -EBADFD;
-       if (nr_segs > 128 || nr_segs != runtime->channels ||
-           !frame_aligned(runtime, iov->iov_len))
+       if (!iter_is_iovec(from))
+               return -EINVAL;
+       if (from->nr_segs > 128 || from->nr_segs != runtime->channels ||
+           !frame_aligned(runtime, from->iov->iov_len))
                return -EINVAL;
-       frames = bytes_to_samples(runtime, iov->iov_len);
-       bufs = kmalloc(sizeof(void *) * nr_segs, GFP_KERNEL);
+       frames = bytes_to_samples(runtime, from->iov->iov_len);
+       bufs = kmalloc(sizeof(void *) * from->nr_segs, GFP_KERNEL);
        if (bufs == NULL)
                return -ENOMEM;
-       for (i = 0; i < nr_segs; ++i)
-               bufs[i] = iov[i].iov_base;
+       for (i = 0; i < from->nr_segs; ++i)
+               bufs[i] = from->iov[i].iov_base;
        result = snd_pcm_lib_writev(substream, bufs, frames);
        if (result > 0)
                result = frames_to_bytes(runtime, result);
@@ -3633,7 +3634,7 @@ const struct file_operations snd_pcm_f_ops[2] = {
        {
                .owner =                THIS_MODULE,
                .write =                snd_pcm_write,
-               .aio_write =            snd_pcm_aio_write,
+               .write_iter =           snd_pcm_writev,
                .open =                 snd_pcm_playback_open,
                .release =              snd_pcm_release,
                .llseek =               no_llseek,
@@ -3647,7 +3648,7 @@ const struct file_operations snd_pcm_f_ops[2] = {
        {
                .owner =                THIS_MODULE,
                .read =                 snd_pcm_read,
-               .aio_read =             snd_pcm_aio_read,
+               .read_iter =            snd_pcm_readv,
                .open =                 snd_pcm_capture_open,
                .release =              snd_pcm_release,
                .llseek =               no_llseek,