aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/direct.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/direct.c')
-rw-r--r--fs/nfs/direct.c46
1 files changed, 28 insertions, 18 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 064a80961677..8eea25366717 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -45,6 +45,7 @@
45#include <linux/pagemap.h> 45#include <linux/pagemap.h>
46#include <linux/kref.h> 46#include <linux/kref.h>
47#include <linux/slab.h> 47#include <linux/slab.h>
48#include <linux/task_io_accounting_ops.h>
48 49
49#include <linux/nfs_fs.h> 50#include <linux/nfs_fs.h>
50#include <linux/nfs_page.h> 51#include <linux/nfs_page.h>
@@ -407,15 +408,18 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,
407 pos += vec->iov_len; 408 pos += vec->iov_len;
408 } 409 }
409 410
411 /*
412 * If no bytes were started, return the error, and let the
413 * generic layer handle the completion.
414 */
415 if (requested_bytes == 0) {
416 nfs_direct_req_release(dreq);
417 return result < 0 ? result : -EIO;
418 }
419
410 if (put_dreq(dreq)) 420 if (put_dreq(dreq))
411 nfs_direct_complete(dreq); 421 nfs_direct_complete(dreq);
412 422 return 0;
413 if (requested_bytes != 0)
414 return 0;
415
416 if (result < 0)
417 return result;
418 return -EIO;
419} 423}
420 424
421static ssize_t nfs_direct_read(struct kiocb *iocb, const struct iovec *iov, 425static ssize_t nfs_direct_read(struct kiocb *iocb, const struct iovec *iov,
@@ -646,8 +650,7 @@ static void nfs_direct_write_result(struct rpc_task *task, void *calldata)
646{ 650{
647 struct nfs_write_data *data = calldata; 651 struct nfs_write_data *data = calldata;
648 652
649 if (nfs_writeback_done(task, data) != 0) 653 nfs_writeback_done(task, data);
650 return;
651} 654}
652 655
653/* 656/*
@@ -841,15 +844,18 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
841 pos += vec->iov_len; 844 pos += vec->iov_len;
842 } 845 }
843 846
847 /*
848 * If no bytes were started, return the error, and let the
849 * generic layer handle the completion.
850 */
851 if (requested_bytes == 0) {
852 nfs_direct_req_release(dreq);
853 return result < 0 ? result : -EIO;
854 }
855
844 if (put_dreq(dreq)) 856 if (put_dreq(dreq))
845 nfs_direct_write_complete(dreq, dreq->inode); 857 nfs_direct_write_complete(dreq, dreq->inode);
846 858 return 0;
847 if (requested_bytes != 0)
848 return 0;
849
850 if (result < 0)
851 return result;
852 return -EIO;
853} 859}
854 860
855static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov, 861static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov,
@@ -867,13 +873,13 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov,
867 goto out; 873 goto out;
868 nfs_alloc_commit_data(dreq); 874 nfs_alloc_commit_data(dreq);
869 875
870 if (dreq->commit_data == NULL || count < wsize) 876 if (dreq->commit_data == NULL || count <= wsize)
871 sync = NFS_FILE_SYNC; 877 sync = NFS_FILE_SYNC;
872 878
873 dreq->inode = inode; 879 dreq->inode = inode;
874 dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp)); 880 dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp));
875 dreq->l_ctx = nfs_get_lock_context(dreq->ctx); 881 dreq->l_ctx = nfs_get_lock_context(dreq->ctx);
876 if (dreq->l_ctx != NULL) 882 if (dreq->l_ctx == NULL)
877 goto out_release; 883 goto out_release;
878 if (!is_sync_kiocb(iocb)) 884 if (!is_sync_kiocb(iocb))
879 dreq->iocb = iocb; 885 dreq->iocb = iocb;
@@ -932,6 +938,8 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, const struct iovec *iov,
932 if (retval) 938 if (retval)
933 goto out; 939 goto out;
934 940
941 task_io_account_read(count);
942
935 retval = nfs_direct_read(iocb, iov, nr_segs, pos); 943 retval = nfs_direct_read(iocb, iov, nr_segs, pos);
936 if (retval > 0) 944 if (retval > 0)
937 iocb->ki_pos = pos + retval; 945 iocb->ki_pos = pos + retval;
@@ -993,6 +1001,8 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov,
993 if (retval) 1001 if (retval)
994 goto out; 1002 goto out;
995 1003
1004 task_io_account_write(count);
1005
996 retval = nfs_direct_write(iocb, iov, nr_segs, pos, count); 1006 retval = nfs_direct_write(iocb, iov, nr_segs, pos, count);
997 1007
998 if (retval > 0) 1008 if (retval > 0)