give ->direct_IO() a copy of iov_iter
authorAl Viro <viro@zeniv.linux.org.uk>
Mon, 10 Mar 2014 18:08:45 +0000 (14:08 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Tue, 6 May 2014 21:32:47 +0000 (17:32 -0400)
the thing is, we want to advance what's given to ->direct_IO() as we
are forming the request; however, the callers care about the amount
of data actually transferred, not the amount we tried to transfer.
It's more convenient to allow ->direct_IO() instances do use
iov_iter_advance() on the copy of iov_iter, leaving the actual
advancing of the original to caller.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
mm/filemap.c

index 70c048e..866f4ae 100644 (file)
@@ -1699,8 +1699,10 @@ generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
                size = i_size_read(inode);
                retval = filemap_write_and_wait_range(mapping, pos,
                                        pos + count - 1);
-               if (!retval)
-                       retval = mapping->a_ops->direct_IO(READ, iocb, &i, pos);
+               if (!retval) {
+                       struct iov_iter data = i;
+                       retval = mapping->a_ops->direct_IO(READ, iocb, &data, pos);
+               }
 
                if (retval > 0) {
                        *ppos = pos + retval;
@@ -2351,6 +2353,7 @@ generic_file_direct_write(struct kiocb *iocb, struct iov_iter *from,
        ssize_t         written;
        size_t          write_len;
        pgoff_t         end;
+       struct iov_iter data;
 
        if (count != ocount)
                from->nr_segs = iov_shorten((struct iovec *)from->iov, from->nr_segs, count);
@@ -2382,7 +2385,8 @@ generic_file_direct_write(struct kiocb *iocb, struct iov_iter *from,
                }
        }
 
-       written = mapping->a_ops->direct_IO(WRITE, iocb, from, pos);
+       data = *from;
+       written = mapping->a_ops->direct_IO(WRITE, iocb, &data, pos);
 
        /*
         * Finally, try again to invalidate clean pages which might have been