aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2014-03-05 19:22:23 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2014-05-06 17:32:48 -0400
commit05bb2e0bc77cb005248be318d2b0ba369b8bbab3 (patch)
tree9bc956f2027ddd5e79d3593d209465cd0778757f /fs/ceph
parent886a39115005ced8b15ab067c9c2a8d546b40a5e (diff)
ceph_aio_read(): keep iov_iter across retries
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/ceph')
-rw-r--r--fs/ceph/file.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 21a56c27b74c..d8f383d59449 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -806,6 +806,9 @@ static ssize_t ceph_aio_read(struct kiocb *iocb, const struct iovec *iov,
806 ssize_t ret; 806 ssize_t ret;
807 int want, got = 0; 807 int want, got = 0;
808 int checkeof = 0, read = 0; 808 int checkeof = 0, read = 0;
809 struct iov_iter i;
810
811 iov_iter_init(&i, iov, nr_segs, len, 0);
809 812
810again: 813again:
811 dout("aio_read %p %llx.%llx %llu~%u trying to get caps on %p\n", 814 dout("aio_read %p %llx.%llx %llu~%u trying to get caps on %p\n",
@@ -822,28 +825,26 @@ again:
822 if ((got & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) == 0 || 825 if ((got & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) == 0 ||
823 (iocb->ki_filp->f_flags & O_DIRECT) || 826 (iocb->ki_filp->f_flags & O_DIRECT) ||
824 (fi->flags & CEPH_F_SYNC)) { 827 (fi->flags & CEPH_F_SYNC)) {
825 struct iov_iter i;
826 828
827 dout("aio_sync_read %p %llx.%llx %llu~%u got cap refs on %s\n", 829 dout("aio_sync_read %p %llx.%llx %llu~%u got cap refs on %s\n",
828 inode, ceph_vinop(inode), iocb->ki_pos, (unsigned)len, 830 inode, ceph_vinop(inode), iocb->ki_pos, (unsigned)len,
829 ceph_cap_string(got)); 831 ceph_cap_string(got));
830 832
831 if (!read)
832 len = iov_length(iov, nr_segs);
833
834 iov_iter_init(&i, iov, nr_segs, len, read);
835
836 /* hmm, this isn't really async... */ 833 /* hmm, this isn't really async... */
837 ret = ceph_sync_read(iocb, &i, &checkeof); 834 ret = ceph_sync_read(iocb, &i, &checkeof);
838 } else { 835 } else {
839 /* 836 /*
840 * We can't modify the content of iov, 837 * We can't modify the content of iov,
841 * so we only read from beginning. 838 * so we only read from beginning.
839 *
840 * When we switch generic_file_aio_read() to iov_iter, the
841 * if () below will be removed -- AV
842 */ 842 */
843 if (read) { 843 if (read) {
844 iocb->ki_pos = pos; 844 iocb->ki_pos = pos;
845 len = iocb->ki_nbytes; 845 len = iocb->ki_nbytes;
846 read = 0; 846 read = 0;
847 iov_iter_init(&i, iov, nr_segs, len, 0);
847 } 848 }
848 dout("aio_read %p %llx.%llx %llu~%u got cap refs on %s\n", 849 dout("aio_read %p %llx.%llx %llu~%u got cap refs on %s\n",
849 inode, ceph_vinop(inode), pos, (unsigned)len, 850 inode, ceph_vinop(inode), pos, (unsigned)len,
@@ -866,6 +867,7 @@ again:
866 ", reading more\n", iocb->ki_pos, 867 ", reading more\n", iocb->ki_pos,
867 inode->i_size); 868 inode->i_size);
868 869
870 iov_iter_advance(&i, ret);
869 read += ret; 871 read += ret;
870 len -= ret; 872 len -= ret;
871 checkeof = 0; 873 checkeof = 0;