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.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 1ba385b7c90d..cae26cbd59ee 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -46,6 +46,7 @@
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#include <linux/task_io_accounting_ops.h>
49#include <linux/module.h>
49 50
50#include <linux/nfs_fs.h> 51#include <linux/nfs_fs.h>
51#include <linux/nfs_page.h> 52#include <linux/nfs_page.h>
@@ -78,6 +79,7 @@ struct nfs_direct_req {
78 atomic_t io_count; /* i/os we're waiting for */ 79 atomic_t io_count; /* i/os we're waiting for */
79 spinlock_t lock; /* protect completion state */ 80 spinlock_t lock; /* protect completion state */
80 ssize_t count, /* bytes actually processed */ 81 ssize_t count, /* bytes actually processed */
82 bytes_left, /* bytes left to be sent */
81 error; /* any reported error */ 83 error; /* any reported error */
82 struct completion completion; /* wait for i/o completion */ 84 struct completion completion; /* wait for i/o completion */
83 85
@@ -190,6 +192,12 @@ static void nfs_direct_req_release(struct nfs_direct_req *dreq)
190 kref_put(&dreq->kref, nfs_direct_req_free); 192 kref_put(&dreq->kref, nfs_direct_req_free);
191} 193}
192 194
195ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq)
196{
197 return dreq->bytes_left;
198}
199EXPORT_SYMBOL_GPL(nfs_dreq_bytes_left);
200
193/* 201/*
194 * Collects and returns the final error value/byte-count. 202 * Collects and returns the final error value/byte-count.
195 */ 203 */
@@ -390,6 +398,7 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_pageio_descriptor *de
390 user_addr += req_len; 398 user_addr += req_len;
391 pos += req_len; 399 pos += req_len;
392 count -= req_len; 400 count -= req_len;
401 dreq->bytes_left -= req_len;
393 } 402 }
394 /* The nfs_page now hold references to these pages */ 403 /* The nfs_page now hold references to these pages */
395 nfs_direct_release_pages(pagevec, npages); 404 nfs_direct_release_pages(pagevec, npages);
@@ -450,23 +459,28 @@ static ssize_t nfs_direct_read(struct kiocb *iocb, const struct iovec *iov,
450 ssize_t result = -ENOMEM; 459 ssize_t result = -ENOMEM;
451 struct inode *inode = iocb->ki_filp->f_mapping->host; 460 struct inode *inode = iocb->ki_filp->f_mapping->host;
452 struct nfs_direct_req *dreq; 461 struct nfs_direct_req *dreq;
462 struct nfs_lock_context *l_ctx;
453 463
454 dreq = nfs_direct_req_alloc(); 464 dreq = nfs_direct_req_alloc();
455 if (dreq == NULL) 465 if (dreq == NULL)
456 goto out; 466 goto out;
457 467
458 dreq->inode = inode; 468 dreq->inode = inode;
469 dreq->bytes_left = iov_length(iov, nr_segs);
459 dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp)); 470 dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp));
460 dreq->l_ctx = nfs_get_lock_context(dreq->ctx); 471 l_ctx = nfs_get_lock_context(dreq->ctx);
461 if (dreq->l_ctx == NULL) 472 if (IS_ERR(l_ctx)) {
473 result = PTR_ERR(l_ctx);
462 goto out_release; 474 goto out_release;
475 }
476 dreq->l_ctx = l_ctx;
463 if (!is_sync_kiocb(iocb)) 477 if (!is_sync_kiocb(iocb))
464 dreq->iocb = iocb; 478 dreq->iocb = iocb;
465 479
480 NFS_I(inode)->read_io += iov_length(iov, nr_segs);
466 result = nfs_direct_read_schedule_iovec(dreq, iov, nr_segs, pos, uio); 481 result = nfs_direct_read_schedule_iovec(dreq, iov, nr_segs, pos, uio);
467 if (!result) 482 if (!result)
468 result = nfs_direct_wait(dreq); 483 result = nfs_direct_wait(dreq);
469 NFS_I(inode)->read_io += result;
470out_release: 484out_release:
471 nfs_direct_req_release(dreq); 485 nfs_direct_req_release(dreq);
472out: 486out:
@@ -706,6 +720,7 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_pageio_descriptor *d
706 user_addr += req_len; 720 user_addr += req_len;
707 pos += req_len; 721 pos += req_len;
708 count -= req_len; 722 count -= req_len;
723 dreq->bytes_left -= req_len;
709 } 724 }
710 /* The nfs_page now hold references to these pages */ 725 /* The nfs_page now hold references to these pages */
711 nfs_direct_release_pages(pagevec, npages); 726 nfs_direct_release_pages(pagevec, npages);
@@ -814,6 +829,7 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
814 get_dreq(dreq); 829 get_dreq(dreq);
815 atomic_inc(&inode->i_dio_count); 830 atomic_inc(&inode->i_dio_count);
816 831
832 NFS_I(dreq->inode)->write_io += iov_length(iov, nr_segs);
817 for (seg = 0; seg < nr_segs; seg++) { 833 for (seg = 0; seg < nr_segs; seg++) {
818 const struct iovec *vec = &iov[seg]; 834 const struct iovec *vec = &iov[seg];
819 result = nfs_direct_write_schedule_segment(&desc, vec, pos, uio); 835 result = nfs_direct_write_schedule_segment(&desc, vec, pos, uio);
@@ -825,7 +841,6 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
825 pos += vec->iov_len; 841 pos += vec->iov_len;
826 } 842 }
827 nfs_pageio_complete(&desc); 843 nfs_pageio_complete(&desc);
828 NFS_I(dreq->inode)->write_io += desc.pg_bytes_written;
829 844
830 /* 845 /*
831 * If no bytes were started, return the error, and let the 846 * If no bytes were started, return the error, and let the
@@ -849,16 +864,21 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov,
849 ssize_t result = -ENOMEM; 864 ssize_t result = -ENOMEM;
850 struct inode *inode = iocb->ki_filp->f_mapping->host; 865 struct inode *inode = iocb->ki_filp->f_mapping->host;
851 struct nfs_direct_req *dreq; 866 struct nfs_direct_req *dreq;
867 struct nfs_lock_context *l_ctx;
852 868
853 dreq = nfs_direct_req_alloc(); 869 dreq = nfs_direct_req_alloc();
854 if (!dreq) 870 if (!dreq)
855 goto out; 871 goto out;
856 872
857 dreq->inode = inode; 873 dreq->inode = inode;
874 dreq->bytes_left = count;
858 dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp)); 875 dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp));
859 dreq->l_ctx = nfs_get_lock_context(dreq->ctx); 876 l_ctx = nfs_get_lock_context(dreq->ctx);
860 if (dreq->l_ctx == NULL) 877 if (IS_ERR(l_ctx)) {
878 result = PTR_ERR(l_ctx);
861 goto out_release; 879 goto out_release;
880 }
881 dreq->l_ctx = l_ctx;
862 if (!is_sync_kiocb(iocb)) 882 if (!is_sync_kiocb(iocb))
863 dreq->iocb = iocb; 883 dreq->iocb = iocb;
864 884