diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2014-04-03 23:09:01 -0400 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2014-05-06 17:39:43 -0400 |
| commit | 4908b822b300d2d7ad0341203181cfbd8a91092a (patch) | |
| tree | 0142ee6c40465aa1a04aec76a25e5c0576f3fed3 | |
| parent | 64c3131161c196ef8e5da8f949334c451fa3521d (diff) | |
ceph: switch to ->write_iter()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
| -rw-r--r-- | fs/ceph/file.c | 57 |
1 files changed, 26 insertions, 31 deletions
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index f68964076c0a..0a1541416fc2 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
| @@ -531,8 +531,7 @@ static void ceph_sync_write_unsafe(struct ceph_osd_request *req, bool unsafe) | |||
| 531 | * objects, rollback on failure, etc.) | 531 | * objects, rollback on failure, etc.) |
| 532 | */ | 532 | */ |
| 533 | static ssize_t | 533 | static ssize_t |
| 534 | ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov, | 534 | ceph_sync_direct_write(struct kiocb *iocb, struct iov_iter *from) |
| 535 | unsigned long nr_segs, size_t count) | ||
| 536 | { | 535 | { |
| 537 | struct file *file = iocb->ki_filp; | 536 | struct file *file = iocb->ki_filp; |
| 538 | struct inode *inode = file_inode(file); | 537 | struct inode *inode = file_inode(file); |
| @@ -549,7 +548,7 @@ ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 549 | int ret; | 548 | int ret; |
| 550 | struct timespec mtime = CURRENT_TIME; | 549 | struct timespec mtime = CURRENT_TIME; |
| 551 | loff_t pos = iocb->ki_pos; | 550 | loff_t pos = iocb->ki_pos; |
| 552 | struct iov_iter i; | 551 | size_t count = iov_iter_count(from); |
| 553 | 552 | ||
| 554 | if (ceph_snap(file_inode(file)) != CEPH_NOSNAP) | 553 | if (ceph_snap(file_inode(file)) != CEPH_NOSNAP) |
| 555 | return -EROFS; | 554 | return -EROFS; |
| @@ -571,10 +570,8 @@ ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 571 | CEPH_OSD_FLAG_ONDISK | | 570 | CEPH_OSD_FLAG_ONDISK | |
| 572 | CEPH_OSD_FLAG_WRITE; | 571 | CEPH_OSD_FLAG_WRITE; |
| 573 | 572 | ||
| 574 | iov_iter_init(&i, WRITE, iov, nr_segs, count); | 573 | while (iov_iter_count(from) > 0) { |
| 575 | 574 | u64 len = iov_iter_single_seg_count(from); | |
| 576 | while (iov_iter_count(&i) > 0) { | ||
| 577 | u64 len = iov_iter_single_seg_count(&i); | ||
| 578 | size_t start; | 575 | size_t start; |
| 579 | ssize_t n; | 576 | ssize_t n; |
| 580 | 577 | ||
| @@ -592,7 +589,7 @@ ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 592 | break; | 589 | break; |
| 593 | } | 590 | } |
| 594 | 591 | ||
| 595 | n = iov_iter_get_pages_alloc(&i, &pages, len, &start); | 592 | n = iov_iter_get_pages_alloc(from, &pages, len, &start); |
| 596 | if (unlikely(n < 0)) { | 593 | if (unlikely(n < 0)) { |
| 597 | ret = n; | 594 | ret = n; |
| 598 | ceph_osdc_put_request(req); | 595 | ceph_osdc_put_request(req); |
| @@ -623,7 +620,7 @@ ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 623 | break; | 620 | break; |
| 624 | pos += n; | 621 | pos += n; |
| 625 | written += n; | 622 | written += n; |
| 626 | iov_iter_advance(&i, n); | 623 | iov_iter_advance(from, n); |
| 627 | 624 | ||
| 628 | if (pos > i_size_read(inode)) { | 625 | if (pos > i_size_read(inode)) { |
| 629 | check_caps = ceph_inode_set_size(inode, pos); | 626 | check_caps = ceph_inode_set_size(inode, pos); |
| @@ -649,8 +646,7 @@ ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 649 | * correct atomic write, we should e.g. take write locks on all | 646 | * correct atomic write, we should e.g. take write locks on all |
| 650 | * objects, rollback on failure, etc.) | 647 | * objects, rollback on failure, etc.) |
| 651 | */ | 648 | */ |
| 652 | static ssize_t ceph_sync_write(struct kiocb *iocb, const struct iovec *iov, | 649 | static ssize_t ceph_sync_write(struct kiocb *iocb, struct iov_iter *from) |
| 653 | unsigned long nr_segs, size_t count) | ||
| 654 | { | 650 | { |
| 655 | struct file *file = iocb->ki_filp; | 651 | struct file *file = iocb->ki_filp; |
| 656 | struct inode *inode = file_inode(file); | 652 | struct inode *inode = file_inode(file); |
| @@ -668,7 +664,7 @@ static ssize_t ceph_sync_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 668 | int ret; | 664 | int ret; |
| 669 | struct timespec mtime = CURRENT_TIME; | 665 | struct timespec mtime = CURRENT_TIME; |
| 670 | loff_t pos = iocb->ki_pos; | 666 | loff_t pos = iocb->ki_pos; |
| 671 | struct iov_iter i; | 667 | size_t count = iov_iter_count(from); |
| 672 | 668 | ||
| 673 | if (ceph_snap(file_inode(file)) != CEPH_NOSNAP) | 669 | if (ceph_snap(file_inode(file)) != CEPH_NOSNAP) |
| 674 | return -EROFS; | 670 | return -EROFS; |
| @@ -690,9 +686,7 @@ static ssize_t ceph_sync_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 690 | CEPH_OSD_FLAG_WRITE | | 686 | CEPH_OSD_FLAG_WRITE | |
| 691 | CEPH_OSD_FLAG_ACK; | 687 | CEPH_OSD_FLAG_ACK; |
| 692 | 688 | ||
| 693 | iov_iter_init(&i, WRITE, iov, nr_segs, count); | 689 | while ((len = iov_iter_count(from)) > 0) { |
| 694 | |||
| 695 | while ((len = iov_iter_count(&i)) > 0) { | ||
| 696 | size_t left; | 690 | size_t left; |
| 697 | int n; | 691 | int n; |
| 698 | 692 | ||
| @@ -724,7 +718,7 @@ static ssize_t ceph_sync_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 724 | left = len; | 718 | left = len; |
| 725 | for (n = 0; n < num_pages; n++) { | 719 | for (n = 0; n < num_pages; n++) { |
| 726 | size_t plen = min_t(size_t, left, PAGE_SIZE); | 720 | size_t plen = min_t(size_t, left, PAGE_SIZE); |
| 727 | ret = copy_page_from_iter(pages[n], 0, plen, &i); | 721 | ret = copy_page_from_iter(pages[n], 0, plen, from); |
| 728 | if (ret != plen) { | 722 | if (ret != plen) { |
| 729 | ret = -EFAULT; | 723 | ret = -EFAULT; |
| 730 | break; | 724 | break; |
| @@ -861,8 +855,7 @@ again: | |||
| 861 | * | 855 | * |
| 862 | * If we are near ENOSPC, write synchronously. | 856 | * If we are near ENOSPC, write synchronously. |
| 863 | */ | 857 | */ |
| 864 | static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov, | 858 | static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from) |
| 865 | unsigned long nr_segs, loff_t pos) | ||
| 866 | { | 859 | { |
| 867 | struct file *file = iocb->ki_filp; | 860 | struct file *file = iocb->ki_filp; |
| 868 | struct ceph_file_info *fi = file->private_data; | 861 | struct ceph_file_info *fi = file->private_data; |
| @@ -870,16 +863,15 @@ static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 870 | struct ceph_inode_info *ci = ceph_inode(inode); | 863 | struct ceph_inode_info *ci = ceph_inode(inode); |
| 871 | struct ceph_osd_client *osdc = | 864 | struct ceph_osd_client *osdc = |
| 872 | &ceph_sb_to_client(inode->i_sb)->client->osdc; | 865 | &ceph_sb_to_client(inode->i_sb)->client->osdc; |
| 873 | ssize_t count, written = 0; | 866 | ssize_t count = iov_iter_count(from), written = 0; |
| 874 | int err, want, got; | 867 | int err, want, got; |
| 868 | loff_t pos = iocb->ki_pos; | ||
| 875 | 869 | ||
| 876 | if (ceph_snap(inode) != CEPH_NOSNAP) | 870 | if (ceph_snap(inode) != CEPH_NOSNAP) |
| 877 | return -EROFS; | 871 | return -EROFS; |
| 878 | 872 | ||
| 879 | mutex_lock(&inode->i_mutex); | 873 | mutex_lock(&inode->i_mutex); |
| 880 | 874 | ||
| 881 | count = iov_length(iov, nr_segs); | ||
| 882 | |||
| 883 | /* We can write back this queue in page reclaim */ | 875 | /* We can write back this queue in page reclaim */ |
| 884 | current->backing_dev_info = file->f_mapping->backing_dev_info; | 876 | current->backing_dev_info = file->f_mapping->backing_dev_info; |
| 885 | 877 | ||
| @@ -889,6 +881,7 @@ static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 889 | 881 | ||
| 890 | if (count == 0) | 882 | if (count == 0) |
| 891 | goto out; | 883 | goto out; |
| 884 | iov_iter_truncate(from, count); | ||
| 892 | 885 | ||
| 893 | err = file_remove_suid(file); | 886 | err = file_remove_suid(file); |
| 894 | if (err) | 887 | if (err) |
| @@ -920,23 +913,26 @@ retry_snap: | |||
| 920 | 913 | ||
| 921 | if ((got & (CEPH_CAP_FILE_BUFFER|CEPH_CAP_FILE_LAZYIO)) == 0 || | 914 | if ((got & (CEPH_CAP_FILE_BUFFER|CEPH_CAP_FILE_LAZYIO)) == 0 || |
| 922 | (file->f_flags & O_DIRECT) || (fi->flags & CEPH_F_SYNC)) { | 915 | (file->f_flags & O_DIRECT) || (fi->flags & CEPH_F_SYNC)) { |
| 916 | struct iov_iter data; | ||
| 923 | mutex_unlock(&inode->i_mutex); | 917 | mutex_unlock(&inode->i_mutex); |
| 918 | /* we might need to revert back to that point */ | ||
| 919 | data = *from; | ||
| 924 | if (file->f_flags & O_DIRECT) | 920 | if (file->f_flags & O_DIRECT) |
| 925 | written = ceph_sync_direct_write(iocb, iov, | 921 | written = ceph_sync_direct_write(iocb, &data); |
| 926 | nr_segs, count); | ||
| 927 | else | 922 | else |
| 928 | written = ceph_sync_write(iocb, iov, nr_segs, count); | 923 | written = ceph_sync_write(iocb, &data); |
| 929 | if (written == -EOLDSNAPC) { | 924 | if (written == -EOLDSNAPC) { |
| 930 | dout("aio_write %p %llx.%llx %llu~%u" | 925 | dout("aio_write %p %llx.%llx %llu~%u" |
| 931 | "got EOLDSNAPC, retrying\n", | 926 | "got EOLDSNAPC, retrying\n", |
| 932 | inode, ceph_vinop(inode), | 927 | inode, ceph_vinop(inode), |
| 933 | pos, (unsigned)iov->iov_len); | 928 | pos, (unsigned)count); |
| 934 | mutex_lock(&inode->i_mutex); | 929 | mutex_lock(&inode->i_mutex); |
| 935 | goto retry_snap; | 930 | goto retry_snap; |
| 936 | } | 931 | } |
| 932 | if (written > 0) | ||
| 933 | iov_iter_advance(from, written); | ||
| 937 | } else { | 934 | } else { |
| 938 | loff_t old_size = inode->i_size; | 935 | loff_t old_size = inode->i_size; |
| 939 | struct iov_iter from; | ||
| 940 | /* | 936 | /* |
| 941 | * No need to acquire the i_truncate_mutex. Because | 937 | * No need to acquire the i_truncate_mutex. Because |
| 942 | * the MDS revokes Fwb caps before sending truncate | 938 | * the MDS revokes Fwb caps before sending truncate |
| @@ -944,8 +940,7 @@ retry_snap: | |||
| 944 | * are pending vmtruncate. So write and vmtruncate | 940 | * are pending vmtruncate. So write and vmtruncate |
| 945 | * can not run at the same time | 941 | * can not run at the same time |
| 946 | */ | 942 | */ |
| 947 | iov_iter_init(&from, WRITE, iov, nr_segs, count); | 943 | written = generic_perform_write(file, from, pos); |
| 948 | written = generic_perform_write(file, &from, pos); | ||
| 949 | if (likely(written >= 0)) | 944 | if (likely(written >= 0)) |
| 950 | iocb->ki_pos = pos + written; | 945 | iocb->ki_pos = pos + written; |
| 951 | if (inode->i_size > old_size) | 946 | if (inode->i_size > old_size) |
| @@ -963,7 +958,7 @@ retry_snap: | |||
| 963 | } | 958 | } |
| 964 | 959 | ||
| 965 | dout("aio_write %p %llx.%llx %llu~%u dropping cap refs on %s\n", | 960 | dout("aio_write %p %llx.%llx %llu~%u dropping cap refs on %s\n", |
| 966 | inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len, | 961 | inode, ceph_vinop(inode), pos, (unsigned)count, |
| 967 | ceph_cap_string(got)); | 962 | ceph_cap_string(got)); |
| 968 | ceph_put_cap_refs(ci, got); | 963 | ceph_put_cap_refs(ci, got); |
| 969 | 964 | ||
| @@ -1241,9 +1236,9 @@ const struct file_operations ceph_file_fops = { | |||
| 1241 | .release = ceph_release, | 1236 | .release = ceph_release, |
| 1242 | .llseek = ceph_llseek, | 1237 | .llseek = ceph_llseek, |
| 1243 | .read = new_sync_read, | 1238 | .read = new_sync_read, |
| 1244 | .write = do_sync_write, | 1239 | .write = new_sync_write, |
| 1245 | .read_iter = ceph_read_iter, | 1240 | .read_iter = ceph_read_iter, |
| 1246 | .aio_write = ceph_aio_write, | 1241 | .write_iter = ceph_write_iter, |
| 1247 | .mmap = ceph_mmap, | 1242 | .mmap = ceph_mmap, |
| 1248 | .fsync = ceph_fsync, | 1243 | .fsync = ceph_fsync, |
| 1249 | .lock = ceph_lock, | 1244 | .lock = ceph_lock, |
