diff options
author | Chuck Lever <cel@netapp.com> | 2006-03-20 13:44:33 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-03-20 13:44:33 -0500 |
commit | c89f2ee5f9223b864725f7344f24a037dfa76568 (patch) | |
tree | b83235bfd96c4a81697609f61b2ce4e3de54e49b /fs/nfs/direct.c | |
parent | 47989d7454398827500d0e73766270986a3b488f (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.c | 46 |
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 | */ | ||
430 | static 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 | |||
450 | static void nfs_direct_write_result(struct rpc_task *task, void *calldata) | 427 | static 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 | */ |
483 | static 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) | 460 | static 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 | ||
542 | static 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) | 523 | static 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); |