diff options
Diffstat (limited to 'fs/ceph/file.c')
-rw-r--r-- | fs/ceph/file.c | 35 |
1 files changed, 16 insertions, 19 deletions
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 2ddf061c1c4a..bc0735498d29 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
@@ -313,9 +313,9 @@ static int striped_read(struct inode *inode, | |||
313 | { | 313 | { |
314 | struct ceph_fs_client *fsc = ceph_inode_to_client(inode); | 314 | struct ceph_fs_client *fsc = ceph_inode_to_client(inode); |
315 | struct ceph_inode_info *ci = ceph_inode(inode); | 315 | struct ceph_inode_info *ci = ceph_inode(inode); |
316 | u64 pos, this_len; | 316 | u64 pos, this_len, left; |
317 | int io_align, page_align; | 317 | int io_align, page_align; |
318 | int left, pages_left; | 318 | int pages_left; |
319 | int read; | 319 | int read; |
320 | struct page **page_pos; | 320 | struct page **page_pos; |
321 | int ret; | 321 | int ret; |
@@ -346,7 +346,7 @@ more: | |||
346 | ret = 0; | 346 | ret = 0; |
347 | hit_stripe = this_len < left; | 347 | hit_stripe = this_len < left; |
348 | was_short = ret >= 0 && ret < this_len; | 348 | was_short = ret >= 0 && ret < this_len; |
349 | dout("striped_read %llu~%u (read %u) got %d%s%s\n", pos, left, read, | 349 | dout("striped_read %llu~%llu (read %u) got %d%s%s\n", pos, left, read, |
350 | ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : ""); | 350 | ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : ""); |
351 | 351 | ||
352 | if (ret > 0) { | 352 | if (ret > 0) { |
@@ -378,7 +378,7 @@ more: | |||
378 | if (pos + left > inode->i_size) | 378 | if (pos + left > inode->i_size) |
379 | left = inode->i_size - pos; | 379 | left = inode->i_size - pos; |
380 | 380 | ||
381 | dout("zero tail %d\n", left); | 381 | dout("zero tail %llu\n", left); |
382 | ceph_zero_page_vector_range(page_align + read, left, | 382 | ceph_zero_page_vector_range(page_align + read, left, |
383 | pages); | 383 | pages); |
384 | read += left; | 384 | read += left; |
@@ -659,7 +659,6 @@ again: | |||
659 | 659 | ||
660 | if ((got & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) == 0 || | 660 | if ((got & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) == 0 || |
661 | (iocb->ki_filp->f_flags & O_DIRECT) || | 661 | (iocb->ki_filp->f_flags & O_DIRECT) || |
662 | (inode->i_sb->s_flags & MS_SYNCHRONOUS) || | ||
663 | (fi->flags & CEPH_F_SYNC)) | 662 | (fi->flags & CEPH_F_SYNC)) |
664 | /* hmm, this isn't really async... */ | 663 | /* hmm, this isn't really async... */ |
665 | ret = ceph_sync_read(filp, base, len, ppos, &checkeof); | 664 | ret = ceph_sync_read(filp, base, len, ppos, &checkeof); |
@@ -711,13 +710,11 @@ static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
711 | &ceph_sb_to_client(inode->i_sb)->client->osdc; | 710 | &ceph_sb_to_client(inode->i_sb)->client->osdc; |
712 | ssize_t count, written = 0; | 711 | ssize_t count, written = 0; |
713 | int err, want, got; | 712 | int err, want, got; |
714 | bool hold_mutex; | ||
715 | 713 | ||
716 | if (ceph_snap(inode) != CEPH_NOSNAP) | 714 | if (ceph_snap(inode) != CEPH_NOSNAP) |
717 | return -EROFS; | 715 | return -EROFS; |
718 | 716 | ||
719 | mutex_lock(&inode->i_mutex); | 717 | mutex_lock(&inode->i_mutex); |
720 | hold_mutex = true; | ||
721 | 718 | ||
722 | err = generic_segment_checks(iov, &nr_segs, &count, VERIFY_READ); | 719 | err = generic_segment_checks(iov, &nr_segs, &count, VERIFY_READ); |
723 | if (err) | 720 | if (err) |
@@ -763,18 +760,24 @@ retry_snap: | |||
763 | 760 | ||
764 | if ((got & (CEPH_CAP_FILE_BUFFER|CEPH_CAP_FILE_LAZYIO)) == 0 || | 761 | if ((got & (CEPH_CAP_FILE_BUFFER|CEPH_CAP_FILE_LAZYIO)) == 0 || |
765 | (iocb->ki_filp->f_flags & O_DIRECT) || | 762 | (iocb->ki_filp->f_flags & O_DIRECT) || |
766 | (inode->i_sb->s_flags & MS_SYNCHRONOUS) || | ||
767 | (fi->flags & CEPH_F_SYNC)) { | 763 | (fi->flags & CEPH_F_SYNC)) { |
768 | mutex_unlock(&inode->i_mutex); | 764 | mutex_unlock(&inode->i_mutex); |
769 | written = ceph_sync_write(file, iov->iov_base, count, | 765 | written = ceph_sync_write(file, iov->iov_base, count, |
770 | pos, &iocb->ki_pos); | 766 | pos, &iocb->ki_pos); |
767 | if (written == -EOLDSNAPC) { | ||
768 | dout("aio_write %p %llx.%llx %llu~%u" | ||
769 | "got EOLDSNAPC, retrying\n", | ||
770 | inode, ceph_vinop(inode), | ||
771 | pos, (unsigned)iov->iov_len); | ||
772 | mutex_lock(&inode->i_mutex); | ||
773 | goto retry_snap; | ||
774 | } | ||
771 | } else { | 775 | } else { |
772 | written = generic_file_buffered_write(iocb, iov, nr_segs, | 776 | written = generic_file_buffered_write(iocb, iov, nr_segs, |
773 | pos, &iocb->ki_pos, | 777 | pos, &iocb->ki_pos, |
774 | count, 0); | 778 | count, 0); |
775 | mutex_unlock(&inode->i_mutex); | 779 | mutex_unlock(&inode->i_mutex); |
776 | } | 780 | } |
777 | hold_mutex = false; | ||
778 | 781 | ||
779 | if (written >= 0) { | 782 | if (written >= 0) { |
780 | int dirty; | 783 | int dirty; |
@@ -798,18 +801,12 @@ retry_snap: | |||
798 | written = err; | 801 | written = err; |
799 | } | 802 | } |
800 | 803 | ||
801 | if (written == -EOLDSNAPC) { | 804 | goto out_unlocked; |
802 | dout("aio_write %p %llx.%llx %llu~%u got EOLDSNAPC, retrying\n", | 805 | |
803 | inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len); | ||
804 | mutex_lock(&inode->i_mutex); | ||
805 | hold_mutex = true; | ||
806 | goto retry_snap; | ||
807 | } | ||
808 | out: | 806 | out: |
809 | if (hold_mutex) | 807 | mutex_unlock(&inode->i_mutex); |
810 | mutex_unlock(&inode->i_mutex); | 808 | out_unlocked: |
811 | current->backing_dev_info = NULL; | 809 | current->backing_dev_info = NULL; |
812 | |||
813 | return written ? written : err; | 810 | return written ? written : err; |
814 | } | 811 | } |
815 | 812 | ||