aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/direct.c91
1 files changed, 41 insertions, 50 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index f8b0a81c340e..cbfbd17eae85 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -898,40 +898,6 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
898 return 0; 898 return 0;
899} 899}
900 900
901static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov,
902 unsigned long nr_segs, loff_t pos,
903 size_t count, bool uio)
904{
905 ssize_t result = -ENOMEM;
906 struct inode *inode = iocb->ki_filp->f_mapping->host;
907 struct nfs_direct_req *dreq;
908 struct nfs_lock_context *l_ctx;
909
910 dreq = nfs_direct_req_alloc();
911 if (!dreq)
912 goto out;
913
914 dreq->inode = inode;
915 dreq->bytes_left = count;
916 dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp));
917 l_ctx = nfs_get_lock_context(dreq->ctx);
918 if (IS_ERR(l_ctx)) {
919 result = PTR_ERR(l_ctx);
920 goto out_release;
921 }
922 dreq->l_ctx = l_ctx;
923 if (!is_sync_kiocb(iocb))
924 dreq->iocb = iocb;
925
926 result = nfs_direct_write_schedule_iovec(dreq, iov, nr_segs, pos, uio);
927 if (!result)
928 result = nfs_direct_wait(dreq);
929out_release:
930 nfs_direct_req_release(dreq);
931out:
932 return result;
933}
934
935/** 901/**
936 * nfs_file_direct_write - file direct write operation for NFS files 902 * nfs_file_direct_write - file direct write operation for NFS files
937 * @iocb: target I/O control block 903 * @iocb: target I/O control block
@@ -957,9 +923,12 @@ out:
957ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov, 923ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov,
958 unsigned long nr_segs, loff_t pos, bool uio) 924 unsigned long nr_segs, loff_t pos, bool uio)
959{ 925{
960 ssize_t retval = -EINVAL; 926 ssize_t result = -EINVAL;
961 struct file *file = iocb->ki_filp; 927 struct file *file = iocb->ki_filp;
962 struct address_space *mapping = file->f_mapping; 928 struct address_space *mapping = file->f_mapping;
929 struct inode *inode = mapping->host;
930 struct nfs_direct_req *dreq;
931 struct nfs_lock_context *l_ctx;
963 size_t count; 932 size_t count;
964 933
965 count = iov_length(iov, nr_segs); 934 count = iov_length(iov, nr_segs);
@@ -968,35 +937,57 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov,
968 dfprintk(FILE, "NFS: direct write(%pD2, %zd@%Ld)\n", 937 dfprintk(FILE, "NFS: direct write(%pD2, %zd@%Ld)\n",
969 file, count, (long long) pos); 938 file, count, (long long) pos);
970 939
971 retval = generic_write_checks(file, &pos, &count, 0); 940 result = generic_write_checks(file, &pos, &count, 0);
972 if (retval) 941 if (result)
973 goto out; 942 goto out;
974 943
975 retval = -EINVAL; 944 result = -EINVAL;
976 if ((ssize_t) count < 0) 945 if ((ssize_t) count < 0)
977 goto out; 946 goto out;
978 retval = 0; 947 result = 0;
979 if (!count) 948 if (!count)
980 goto out; 949 goto out;
981 950
982 retval = nfs_sync_mapping(mapping); 951 result = nfs_sync_mapping(mapping);
983 if (retval) 952 if (result)
984 goto out; 953 goto out;
985 954
986 task_io_account_write(count); 955 task_io_account_write(count);
987 956
988 retval = nfs_direct_write(iocb, iov, nr_segs, pos, count, uio); 957 result = -ENOMEM;
989 if (retval > 0) { 958 dreq = nfs_direct_req_alloc();
990 struct inode *inode = mapping->host; 959 if (!dreq)
960 goto out;
991 961
992 iocb->ki_pos = pos + retval; 962 dreq->inode = inode;
993 spin_lock(&inode->i_lock); 963 dreq->bytes_left = count;
994 if (i_size_read(inode) < iocb->ki_pos) 964 dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp));
995 i_size_write(inode, iocb->ki_pos); 965 l_ctx = nfs_get_lock_context(dreq->ctx);
996 spin_unlock(&inode->i_lock); 966 if (IS_ERR(l_ctx)) {
967 result = PTR_ERR(l_ctx);
968 goto out_release;
969 }
970 dreq->l_ctx = l_ctx;
971 if (!is_sync_kiocb(iocb))
972 dreq->iocb = iocb;
973
974 result = nfs_direct_write_schedule_iovec(dreq, iov, nr_segs, pos, uio);
975 if (!result) {
976 result = nfs_direct_wait(dreq);
977 if (result > 0) {
978 struct inode *inode = mapping->host;
979
980 iocb->ki_pos = pos + result;
981 spin_lock(&inode->i_lock);
982 if (i_size_read(inode) < iocb->ki_pos)
983 i_size_write(inode, iocb->ki_pos);
984 spin_unlock(&inode->i_lock);
985 }
997 } 986 }
987out_release:
988 nfs_direct_req_release(dreq);
998out: 989out:
999 return retval; 990 return result;
1000} 991}
1001 992
1002/** 993/**