iov_iter_truncate()
authorAl Viro <viro@zeniv.linux.org.uk>
Sat, 22 Mar 2014 10:51:37 +0000 (06:51 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Tue, 6 May 2014 21:32:54 +0000 (17:32 -0400)
Now It Can Be Done(tm) - we don't need to do iov_shorten() in
generic_file_direct_write() anymore, now that all ->direct_IO()
instances are converted to proper iov_iter methods and honour
iter->count and iter->iov_offset properly.

Get rid of count/ocount arguments of generic_file_direct_write(),
while we are at it.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/btrfs/file.c
fs/fuse/file.c
fs/ocfs2/file.c
fs/xfs/xfs_file.c
include/linux/fs.h
include/linux/uio.h
mm/filemap.c

index f8cee205618a57b0b02cf588aec6c2ebf10af544..ea63a51c148cf60fd270b96c69f82f620dfe16fc 100644 (file)
@@ -1659,8 +1659,7 @@ again:
 
 static ssize_t __btrfs_direct_write(struct kiocb *iocb,
                                    struct iov_iter *from,
-                                   loff_t pos,
-                                   size_t count, size_t ocount)
+                                   loff_t pos)
 {
        struct file *file = iocb->ki_filp;
        ssize_t written;
@@ -1668,9 +1667,9 @@ static ssize_t __btrfs_direct_write(struct kiocb *iocb,
        loff_t endbyte;
        int err;
 
-       written = generic_file_direct_write(iocb, from, pos, count, ocount);
+       written = generic_file_direct_write(iocb, from, pos);
 
-       if (written < 0 || written == count)
+       if (written < 0 || !iov_iter_count(from))
                return written;
 
        pos += written;
@@ -1720,13 +1719,14 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
        u64 end_pos;
        ssize_t num_written = 0;
        ssize_t err = 0;
-       size_t count, ocount;
+       size_t count;
        bool sync = (file->f_flags & O_DSYNC) || IS_SYNC(file->f_mapping->host);
        struct iov_iter i;
 
        mutex_lock(&inode->i_mutex);
 
-       count = ocount = iov_length(iov, nr_segs);
+       count = iov_length(iov, nr_segs);
+       iov_iter_init(&i, WRITE, iov, nr_segs, count);
 
        current->backing_dev_info = inode->i_mapping->backing_dev_info;
        err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode));
@@ -1740,7 +1740,7 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
                goto out;
        }
 
-       iov_iter_init(&i, WRITE, iov, nr_segs, count);
+       iov_iter_truncate(&i, count);
 
        err = file_remove_suid(file);
        if (err) {
@@ -1783,8 +1783,7 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
                atomic_inc(&BTRFS_I(inode)->sync_writers);
 
        if (unlikely(file->f_flags & O_DIRECT)) {
-               num_written = __btrfs_direct_write(iocb, &i,
-                                                  pos, count, ocount);
+               num_written = __btrfs_direct_write(iocb, &i, pos);
        } else {
                num_written = __btrfs_buffered_write(file, &i, pos);
                if (num_written > 0)
index 7026014717bcd37069921b928f4877568d63d3bf..66d2d5de19d21420f23a1848f2587a5407a6945c 100644 (file)
@@ -1188,8 +1188,7 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 {
        struct file *file = iocb->ki_filp;
        struct address_space *mapping = file->f_mapping;
-       size_t count = 0;
-       size_t ocount = 0;
+       size_t count;
        ssize_t written = 0;
        ssize_t written_buffered = 0;
        struct inode *inode = mapping->host;
@@ -1208,7 +1207,8 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 
        WARN_ON(iocb->ki_pos != pos);
 
-       count = ocount = iov_length(iov, nr_segs);
+       count = iov_length(iov, nr_segs);
+       iov_iter_init(&i, WRITE, iov, nr_segs, count);
        mutex_lock(&inode->i_mutex);
 
        /* We can write back this queue in page reclaim */
@@ -1217,11 +1217,11 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
        err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode));
        if (err)
                goto out;
-       iov_iter_init(&i, WRITE, iov, nr_segs, count);
 
        if (count == 0)
                goto out;
 
+       iov_iter_truncate(&i, count);
        err = file_remove_suid(file);
        if (err)
                goto out;
@@ -1231,8 +1231,8 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
                goto out;
 
        if (file->f_flags & O_DIRECT) {
-               written = generic_file_direct_write(iocb, &i, pos, count, ocount);
-               if (written < 0 || written == count)
+               written = generic_file_direct_write(iocb, &i, pos);
+               if (written < 0 || !iov_iter_count(&i))
                        goto out;
 
                pos += written;
@@ -1469,8 +1469,7 @@ static ssize_t __fuse_direct_write(struct fuse_io_priv *io,
 
        res = generic_write_checks(file, ppos, &count, 0);
        if (!res) {
-               if (iter->count > count)
-                       iter->count = count;
+               iov_iter_truncate(iter, count);
                res = fuse_direct_io(io, iter, ppos, FUSE_DIO_WRITE);
        }
 
@@ -2896,8 +2895,7 @@ fuse_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter,
                if (offset >= i_size)
                        return 0;
                count = min_t(loff_t, count, fuse_round_up(i_size - offset));
-               if (iter->count > count)
-                       iter->count = count;
+               iov_iter_truncate(iter, count);
        }
 
        io = kmalloc(sizeof(struct fuse_io_priv), GFP_KERNEL);
index 9ce9ed7615c1daafa5cfc36f51d5f93f495cdbc4..06b6a16d9776e9768b3c0db49c56ae9342ab0638 100644 (file)
@@ -2241,7 +2241,6 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
        int ret, direct_io, appending, rw_level, have_alloc_sem  = 0;
        int can_do_direct, has_refcount = 0;
        ssize_t written = 0;
-       size_t ocount;          /* original count */
        size_t count;           /* after file limit checks */
        loff_t old_size, *ppos = &iocb->ki_pos;
        u32 old_clusters;
@@ -2253,6 +2252,9 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
        int unaligned_dio = 0;
        struct iov_iter from;
 
+       count = iov_length(iov, nr_segs);
+       iov_iter_init(&from, WRITE, iov, nr_segs, count);
+
        trace_ocfs2_file_aio_write(inode, file, file->f_path.dentry,
                (unsigned long long)OCFS2_I(inode)->ip_blkno,
                file->f_path.dentry->d_name.len,
@@ -2355,16 +2357,14 @@ relock:
        /* communicate with ocfs2_dio_end_io */
        ocfs2_iocb_set_rw_locked(iocb, rw_level);
 
-       count = ocount = iov_length(iov, nr_segs);
        ret = generic_write_checks(file, ppos, &count,
                                   S_ISBLK(inode->i_mode));
        if (ret)
                goto out_dio;
 
-       iov_iter_init(&from, WRITE, iov, nr_segs, count);
+       iov_iter_truncate(&from, count);
        if (direct_io) {
-               written = generic_file_direct_write(iocb, &from, *ppos,
-                                                   count, ocount);
+               written = generic_file_direct_write(iocb, &from, *ppos);
                if (written < 0) {
                        ret = written;
                        goto out_dio;
index 762bb3e148a61b05bb662a5289d62f644dbdc450..c997aa2751b220473646ef454be1594d9ad76774 100644 (file)
@@ -626,7 +626,7 @@ xfs_file_dio_aio_write(
        const struct iovec      *iovp,
        unsigned long           nr_segs,
        loff_t                  pos,
-       size_t                  ocount)
+       size_t                  count)
 {
        struct file             *file = iocb->ki_filp;
        struct address_space    *mapping = file->f_mapping;
@@ -634,7 +634,6 @@ xfs_file_dio_aio_write(
        struct xfs_inode        *ip = XFS_I(inode);
        struct xfs_mount        *mp = ip->i_mount;
        ssize_t                 ret = 0;
-       size_t                  count = ocount;
        int                     unaligned_io = 0;
        int                     iolock;
        struct xfs_buftarg      *target = XFS_IS_REALTIME_INODE(ip) ?
@@ -645,6 +644,8 @@ xfs_file_dio_aio_write(
        if ((pos | count) & target->bt_logical_sectormask)
                return -XFS_ERROR(EINVAL);
 
+       iov_iter_init(&from, WRITE, iovp, nr_segs, count);
+
        /* "unaligned" here means not aligned to a filesystem block */
        if ((pos & mp->m_blockmask) || ((pos + count) & mp->m_blockmask))
                unaligned_io = 1;
@@ -676,6 +677,7 @@ xfs_file_dio_aio_write(
        ret = xfs_file_aio_write_checks(file, &pos, &count, &iolock);
        if (ret)
                goto out;
+       iov_iter_truncate(&from, count);
 
        if (mapping->nrpages) {
                ret = filemap_write_and_wait_range(VFS_I(ip)->i_mapping,
@@ -697,8 +699,7 @@ xfs_file_dio_aio_write(
        }
 
        trace_xfs_file_direct_write(ip, count, iocb->ki_pos, 0);
-       iov_iter_init(&from, WRITE, iovp, nr_segs, count);
-       ret = generic_file_direct_write(iocb, &from, pos, count, ocount);
+       ret = generic_file_direct_write(iocb, &from, pos);
 
 out:
        xfs_rw_iunlock(ip, iolock);
index d096ebc7f348fb5d847ae92292c8acd83cfa21da..8153396d19b497ebd5f0316b3ccaa71b913495b1 100644 (file)
@@ -2407,8 +2407,7 @@ extern ssize_t generic_file_aio_read(struct kiocb *, const struct iovec *, unsig
 extern ssize_t generic_file_read_iter(struct kiocb *, struct iov_iter *);
 extern ssize_t __generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long);
 extern ssize_t generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long, loff_t);
-extern ssize_t generic_file_direct_write(struct kiocb *, struct iov_iter *,
-               loff_t, size_t, size_t);
+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);
index 4876e9f2a58f43b7178617d9b9c1a71d5ad75986..532f59d0adbb6ef59f390e24a7368d07b723e36e 100644 (file)
@@ -82,6 +82,12 @@ static inline size_t iov_iter_count(struct iov_iter *i)
        return i->count;
 }
 
+static inline void iov_iter_truncate(struct iov_iter *i, size_t count)
+{
+       if (i->count > count)
+               i->count = count;
+}
+
 int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len);
 int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len);
 
index 3aeaf2df4135fd726957b7f4bff38b3df3d7ab61..c0404b763a17fb48832b58ac0137589148da915c 100644 (file)
@@ -2345,8 +2345,7 @@ int pagecache_write_end(struct file *file, struct address_space *mapping,
 EXPORT_SYMBOL(pagecache_write_end);
 
 ssize_t
-generic_file_direct_write(struct kiocb *iocb, struct iov_iter *from,
-               loff_t pos, size_t count, size_t ocount)
+generic_file_direct_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos)
 {
        struct file     *file = iocb->ki_filp;
        struct address_space *mapping = file->f_mapping;
@@ -2356,10 +2355,7 @@ generic_file_direct_write(struct kiocb *iocb, struct iov_iter *from,
        pgoff_t         end;
        struct iov_iter data;
 
-       if (count != ocount)
-               from->nr_segs = iov_shorten((struct iovec *)from->iov, from->nr_segs, count);
-
-       write_len = iov_length(from->iov, from->nr_segs);
+       write_len = iov_iter_count(from);
        end = (pos + write_len - 1) >> PAGE_CACHE_SHIFT;
 
        written = filemap_write_and_wait_range(mapping, pos, pos + write_len - 1);
@@ -2568,7 +2564,6 @@ ssize_t __generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 {
        struct file *file = iocb->ki_filp;
        struct address_space * mapping = file->f_mapping;
-       size_t ocount;          /* original count */
        size_t count;           /* after file limit checks */
        struct inode    *inode = mapping->host;
        loff_t          pos = iocb->ki_pos;
@@ -2577,7 +2572,8 @@ ssize_t __generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
        ssize_t         status;
        struct iov_iter from;
 
-       count = ocount = iov_length(iov, nr_segs);
+       count = iov_length(iov, nr_segs);
+       iov_iter_init(&from, WRITE, iov, nr_segs, count);
 
        /* We can write back this queue in page reclaim */
        current->backing_dev_info = mapping->backing_dev_info;
@@ -2588,6 +2584,8 @@ ssize_t __generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
        if (count == 0)
                goto out;
 
+       iov_iter_truncate(&from, count);
+
        err = file_remove_suid(file);
        if (err)
                goto out;
@@ -2596,14 +2594,11 @@ ssize_t __generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
        if (err)
                goto out;
 
-       iov_iter_init(&from, WRITE, iov, nr_segs, count);
-
        /* coalesce the iovecs and go direct-to-BIO for O_DIRECT */
        if (unlikely(file->f_flags & O_DIRECT)) {
                loff_t endbyte;
 
-               written = generic_file_direct_write(iocb, &from, pos,
-                                                       count, ocount);
+               written = generic_file_direct_write(iocb, &from, pos);
                if (written < 0 || written == count)
                        goto out;