aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/direct.c
diff options
context:
space:
mode:
authorChuck Lever <cel@netapp.com>2006-03-20 13:44:33 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-03-20 13:44:33 -0500
commitc89f2ee5f9223b864725f7344f24a037dfa76568 (patch)
treeb83235bfd96c4a81697609f61b2ce4e3de54e49b /fs/nfs/direct.c
parent47989d7454398827500d0e73766270986a3b488f (diff)
NFS: make iocb available everywhere in direct write path
Pass the iocb argument all the way down to the direct write request scheduler, and make it available in nfs_direct_write_result. Test plan: Compile the kernel with CONFIG_NFS and CONFIG_NFS_DIRECTIO enabled. Millions of fsx-odirect ops. OraSim. Signed-off-by: Chuck Lever <cel@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/direct.c')
-rw-r--r--fs/nfs/direct.c46
1 files changed, 14 insertions, 32 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 9a7d45907054..9d57a299824c 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -424,29 +424,6 @@ static struct nfs_direct_req *nfs_direct_write_alloc(size_t nbytes, size_t wsize
424 return dreq; 424 return dreq;
425} 425}
426 426
427/*
428 * Collects and returns the final error value/byte-count.
429 */
430static ssize_t nfs_direct_write_wait(struct nfs_direct_req *dreq, int intr)
431{
432 int result = 0;
433
434 if (intr) {
435 result = wait_event_interruptible(dreq->wait,
436 (atomic_read(&dreq->complete) == 0));
437 } else {
438 wait_event(dreq->wait, (atomic_read(&dreq->complete) == 0));
439 }
440
441 if (!result)
442 result = atomic_read(&dreq->error);
443 if (!result)
444 result = atomic_read(&dreq->count);
445
446 kref_put(&dreq->kref, nfs_direct_req_release);
447 return (ssize_t) result;
448}
449
450static void nfs_direct_write_result(struct rpc_task *task, void *calldata) 427static void nfs_direct_write_result(struct rpc_task *task, void *calldata)
451{ 428{
452 struct nfs_write_data *data = calldata; 429 struct nfs_write_data *data = calldata;
@@ -480,8 +457,12 @@ static const struct rpc_call_ops nfs_write_direct_ops = {
480 * XXX: For now, support only FILE_SYNC writes. Later we may add 457 * XXX: For now, support only FILE_SYNC writes. Later we may add
481 * support for UNSTABLE + COMMIT. 458 * support for UNSTABLE + COMMIT.
482 */ 459 */
483static void nfs_direct_write_schedule(struct nfs_direct_req *dreq, struct inode *inode, struct nfs_open_context *ctx, unsigned long user_addr, size_t count, loff_t file_offset) 460static void nfs_direct_write_schedule(struct nfs_direct_req *dreq, unsigned long user_addr, size_t count, loff_t file_offset)
484{ 461{
462 struct file *file = dreq->filp;
463 struct inode *inode = file->f_mapping->host;
464 struct nfs_open_context *ctx = (struct nfs_open_context *)
465 file->private_data;
485 struct list_head *list = &dreq->list; 466 struct list_head *list = &dreq->list;
486 struct page **pages = dreq->pages; 467 struct page **pages = dreq->pages;
487 size_t wsize = NFS_SERVER(inode)->wsize; 468 size_t wsize = NFS_SERVER(inode)->wsize;
@@ -539,10 +520,11 @@ static void nfs_direct_write_schedule(struct nfs_direct_req *dreq, struct inode
539 } while (count != 0); 520 } while (count != 0);
540} 521}
541 522
542static ssize_t nfs_direct_write(struct inode *inode, struct nfs_open_context *ctx, unsigned long user_addr, size_t count, loff_t file_offset, struct page **pages, int nr_pages) 523static ssize_t nfs_direct_write(struct kiocb *iocb, unsigned long user_addr, size_t count, loff_t file_offset, struct page **pages, int nr_pages)
543{ 524{
544 ssize_t result; 525 ssize_t result;
545 sigset_t oldset; 526 sigset_t oldset;
527 struct inode *inode = iocb->ki_filp->f_mapping->host;
546 struct rpc_clnt *clnt = NFS_CLIENT(inode); 528 struct rpc_clnt *clnt = NFS_CLIENT(inode);
547 struct nfs_direct_req *dreq; 529 struct nfs_direct_req *dreq;
548 530
@@ -552,15 +534,18 @@ static ssize_t nfs_direct_write(struct inode *inode, struct nfs_open_context *ct
552 534
553 dreq->pages = pages; 535 dreq->pages = pages;
554 dreq->npages = nr_pages; 536 dreq->npages = nr_pages;
537 dreq->inode = inode;
538 dreq->filp = iocb->ki_filp;
539 if (!is_sync_kiocb(iocb))
540 dreq->iocb = iocb;
555 541
556 nfs_add_stats(inode, NFSIOS_DIRECTWRITTENBYTES, count); 542 nfs_add_stats(inode, NFSIOS_DIRECTWRITTENBYTES, count);
557 543
558 nfs_begin_data_update(inode); 544 nfs_begin_data_update(inode);
559 545
560 rpc_clnt_sigmask(clnt, &oldset); 546 rpc_clnt_sigmask(clnt, &oldset);
561 nfs_direct_write_schedule(dreq, inode, ctx, user_addr, count, 547 nfs_direct_write_schedule(dreq, user_addr, count, file_offset);
562 file_offset); 548 result = nfs_direct_wait(dreq);
563 result = nfs_direct_write_wait(dreq, clnt->cl_intr);
564 rpc_clnt_sigunmask(clnt, &oldset); 549 rpc_clnt_sigunmask(clnt, &oldset);
565 550
566 nfs_end_data_update(inode); 551 nfs_end_data_update(inode);
@@ -663,10 +648,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, const char __user *buf, size_t
663 int page_count; 648 int page_count;
664 struct page **pages; 649 struct page **pages;
665 struct file *file = iocb->ki_filp; 650 struct file *file = iocb->ki_filp;
666 struct nfs_open_context *ctx =
667 (struct nfs_open_context *) file->private_data;
668 struct address_space *mapping = file->f_mapping; 651 struct address_space *mapping = file->f_mapping;
669 struct inode *inode = mapping->host;
670 652
671 dfprintk(VFS, "nfs: direct write(%s/%s, %lu@%Ld)\n", 653 dfprintk(VFS, "nfs: direct write(%s/%s, %lu@%Ld)\n",
672 file->f_dentry->d_parent->d_name.name, 654 file->f_dentry->d_parent->d_name.name,
@@ -704,7 +686,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, const char __user *buf, size_t
704 goto out; 686 goto out;
705 } 687 }
706 688
707 retval = nfs_direct_write(inode, ctx, (unsigned long) buf, count, 689 retval = nfs_direct_write(iocb, (unsigned long) buf, count,
708 pos, pages, page_count); 690 pos, pages, page_count);
709 if (mapping->nrpages) 691 if (mapping->nrpages)
710 invalidate_inode_pages2(mapping); 692 invalidate_inode_pages2(mapping);