ceph_aio_read(): keep iov_iter across retries
authorAl Viro <viro@zeniv.linux.org.uk>
Thu, 6 Mar 2014 00:22:23 +0000 (19:22 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Tue, 6 May 2014 21:32:48 +0000 (17:32 -0400)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/ceph/file.c

index 21a56c27b74c347ed51492afaf16ff166d3440de..d8f383d59449abccd6bafa123e0c753bae6de6c6 100644 (file)
@@ -806,6 +806,9 @@ static ssize_t ceph_aio_read(struct kiocb *iocb, const struct iovec *iov,
        ssize_t ret;
        int want, got = 0;
        int checkeof = 0, read = 0;
+       struct iov_iter i;
+
+       iov_iter_init(&i, iov, nr_segs, len, 0);
 
 again:
        dout("aio_read %p %llx.%llx %llu~%u trying to get caps on %p\n",
@@ -822,28 +825,26 @@ again:
        if ((got & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) == 0 ||
            (iocb->ki_filp->f_flags & O_DIRECT) ||
            (fi->flags & CEPH_F_SYNC)) {
-               struct iov_iter i;
 
                dout("aio_sync_read %p %llx.%llx %llu~%u got cap refs on %s\n",
                     inode, ceph_vinop(inode), iocb->ki_pos, (unsigned)len,
                     ceph_cap_string(got));
 
-               if (!read)
-                       len = iov_length(iov, nr_segs);
-
-               iov_iter_init(&i, iov, nr_segs, len, read);
-
                /* hmm, this isn't really async... */
                ret = ceph_sync_read(iocb, &i, &checkeof);
        } else {
                /*
                 * We can't modify the content of iov,
                 * so we only read from beginning.
+                *
+                * When we switch generic_file_aio_read() to iov_iter, the
+                * if () below will be removed -- AV
                 */
                if (read) {
                        iocb->ki_pos = pos;
                        len = iocb->ki_nbytes;
                        read = 0;
+                       iov_iter_init(&i, iov, nr_segs, len, 0);
                }
                dout("aio_read %p %llx.%llx %llu~%u got cap refs on %s\n",
                     inode, ceph_vinop(inode), pos, (unsigned)len,
@@ -866,6 +867,7 @@ again:
                             ", reading more\n", iocb->ki_pos,
                             inode->i_size);
 
+                       iov_iter_advance(&i, ret);
                        read += ret;
                        len -= ret;
                        checkeof = 0;