aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2014-04-03 23:09:01 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2014-05-06 17:39:43 -0400
commit4908b822b300d2d7ad0341203181cfbd8a91092a (patch)
tree0142ee6c40465aa1a04aec76a25e5c0576f3fed3 /fs
parent64c3131161c196ef8e5da8f949334c451fa3521d (diff)
ceph: switch to ->write_iter()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r--fs/ceph/file.c57
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 */
533static ssize_t 533static ssize_t
534ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov, 534ceph_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 */
652static ssize_t ceph_sync_write(struct kiocb *iocb, const struct iovec *iov, 649static 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 */
864static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov, 858static 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,