diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2014-03-05 19:22:23 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2014-05-06 17:32:48 -0400 |
commit | 05bb2e0bc77cb005248be318d2b0ba369b8bbab3 (patch) | |
tree | 9bc956f2027ddd5e79d3593d209465cd0778757f /fs/ceph | |
parent | 886a39115005ced8b15ab067c9c2a8d546b40a5e (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.c | 14 |
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 | ||
810 | again: | 813 | again: |
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; |