diff options
Diffstat (limited to 'fs/nfs/direct.c')
-rw-r--r-- | fs/nfs/direct.c | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 5bcc764e501a..244d1bd7002c 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
@@ -272,8 +272,12 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq, | |||
272 | unsigned long user_addr = (unsigned long)iov->iov_base; | 272 | unsigned long user_addr = (unsigned long)iov->iov_base; |
273 | size_t count = iov->iov_len; | 273 | size_t count = iov->iov_len; |
274 | size_t rsize = NFS_SERVER(inode)->rsize; | 274 | size_t rsize = NFS_SERVER(inode)->rsize; |
275 | struct rpc_message msg = { | ||
276 | .rpc_cred = ctx->cred, | ||
277 | }; | ||
275 | struct rpc_task_setup task_setup_data = { | 278 | struct rpc_task_setup task_setup_data = { |
276 | .rpc_client = NFS_CLIENT(inode), | 279 | .rpc_client = NFS_CLIENT(inode), |
280 | .rpc_message = &msg, | ||
277 | .callback_ops = &nfs_read_direct_ops, | 281 | .callback_ops = &nfs_read_direct_ops, |
278 | .flags = RPC_TASK_ASYNC, | 282 | .flags = RPC_TASK_ASYNC, |
279 | }; | 283 | }; |
@@ -316,7 +320,7 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq, | |||
316 | 320 | ||
317 | data->req = (struct nfs_page *) dreq; | 321 | data->req = (struct nfs_page *) dreq; |
318 | data->inode = inode; | 322 | data->inode = inode; |
319 | data->cred = ctx->cred; | 323 | data->cred = msg.rpc_cred; |
320 | data->args.fh = NFS_FH(inode); | 324 | data->args.fh = NFS_FH(inode); |
321 | data->args.context = ctx; | 325 | data->args.context = ctx; |
322 | data->args.offset = pos; | 326 | data->args.offset = pos; |
@@ -326,10 +330,12 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq, | |||
326 | data->res.fattr = &data->fattr; | 330 | data->res.fattr = &data->fattr; |
327 | data->res.eof = 0; | 331 | data->res.eof = 0; |
328 | data->res.count = bytes; | 332 | data->res.count = bytes; |
333 | msg.rpc_argp = &data->args; | ||
334 | msg.rpc_resp = &data->res; | ||
329 | 335 | ||
330 | task_setup_data.callback_data = data; | 336 | task_setup_data.callback_data = data; |
337 | NFS_PROTO(inode)->read_setup(data, &msg); | ||
331 | rpc_init_task(&data->task, &task_setup_data); | 338 | rpc_init_task(&data->task, &task_setup_data); |
332 | NFS_PROTO(inode)->read_setup(data); | ||
333 | 339 | ||
334 | rpc_execute(&data->task); | 340 | rpc_execute(&data->task); |
335 | 341 | ||
@@ -434,6 +440,9 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) | |||
434 | struct inode *inode = dreq->inode; | 440 | struct inode *inode = dreq->inode; |
435 | struct list_head *p; | 441 | struct list_head *p; |
436 | struct nfs_write_data *data; | 442 | struct nfs_write_data *data; |
443 | struct rpc_message msg = { | ||
444 | .rpc_cred = dreq->ctx->cred, | ||
445 | }; | ||
437 | struct rpc_task_setup task_setup_data = { | 446 | struct rpc_task_setup task_setup_data = { |
438 | .rpc_client = NFS_CLIENT(inode), | 447 | .rpc_client = NFS_CLIENT(inode), |
439 | .callback_ops = &nfs_write_direct_ops, | 448 | .callback_ops = &nfs_write_direct_ops, |
@@ -448,6 +457,9 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) | |||
448 | 457 | ||
449 | get_dreq(dreq); | 458 | get_dreq(dreq); |
450 | 459 | ||
460 | /* Use stable writes */ | ||
461 | data->args.stable = NFS_FILE_SYNC; | ||
462 | |||
451 | /* | 463 | /* |
452 | * Reset data->res. | 464 | * Reset data->res. |
453 | */ | 465 | */ |
@@ -460,8 +472,10 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) | |||
460 | * since the original request was sent. | 472 | * since the original request was sent. |
461 | */ | 473 | */ |
462 | task_setup_data.callback_data = data; | 474 | task_setup_data.callback_data = data; |
475 | msg.rpc_argp = &data->args; | ||
476 | msg.rpc_resp = &data->res; | ||
477 | NFS_PROTO(inode)->write_setup(data, &msg); | ||
463 | rpc_init_task(&data->task, &task_setup_data); | 478 | rpc_init_task(&data->task, &task_setup_data); |
464 | NFS_PROTO(inode)->write_setup(data, FLUSH_STABLE); | ||
465 | 479 | ||
466 | /* | 480 | /* |
467 | * We're called via an RPC callback, so BKL is already held. | 481 | * We're called via an RPC callback, so BKL is already held. |
@@ -509,15 +523,21 @@ static const struct rpc_call_ops nfs_commit_direct_ops = { | |||
509 | static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) | 523 | static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) |
510 | { | 524 | { |
511 | struct nfs_write_data *data = dreq->commit_data; | 525 | struct nfs_write_data *data = dreq->commit_data; |
526 | struct rpc_message msg = { | ||
527 | .rpc_argp = &data->args, | ||
528 | .rpc_resp = &data->res, | ||
529 | .rpc_cred = dreq->ctx->cred, | ||
530 | }; | ||
512 | struct rpc_task_setup task_setup_data = { | 531 | struct rpc_task_setup task_setup_data = { |
513 | .rpc_client = NFS_CLIENT(dreq->inode), | 532 | .rpc_client = NFS_CLIENT(dreq->inode), |
533 | .rpc_message = &msg, | ||
514 | .callback_ops = &nfs_commit_direct_ops, | 534 | .callback_ops = &nfs_commit_direct_ops, |
515 | .callback_data = data, | 535 | .callback_data = data, |
516 | .flags = RPC_TASK_ASYNC, | 536 | .flags = RPC_TASK_ASYNC, |
517 | }; | 537 | }; |
518 | 538 | ||
519 | data->inode = dreq->inode; | 539 | data->inode = dreq->inode; |
520 | data->cred = dreq->ctx->cred; | 540 | data->cred = msg.rpc_cred; |
521 | 541 | ||
522 | data->args.fh = NFS_FH(data->inode); | 542 | data->args.fh = NFS_FH(data->inode); |
523 | data->args.offset = 0; | 543 | data->args.offset = 0; |
@@ -526,8 +546,8 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) | |||
526 | data->res.fattr = &data->fattr; | 546 | data->res.fattr = &data->fattr; |
527 | data->res.verf = &data->verf; | 547 | data->res.verf = &data->verf; |
528 | 548 | ||
549 | NFS_PROTO(data->inode)->commit_setup(data, &msg); | ||
529 | rpc_init_task(&data->task, &task_setup_data); | 550 | rpc_init_task(&data->task, &task_setup_data); |
530 | NFS_PROTO(data->inode)->commit_setup(data, 0); | ||
531 | 551 | ||
532 | /* Note: task.tk_ops->rpc_release will free dreq->commit_data */ | 552 | /* Note: task.tk_ops->rpc_release will free dreq->commit_data */ |
533 | dreq->commit_data = NULL; | 553 | dreq->commit_data = NULL; |
@@ -649,8 +669,12 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq, | |||
649 | struct inode *inode = ctx->path.dentry->d_inode; | 669 | struct inode *inode = ctx->path.dentry->d_inode; |
650 | unsigned long user_addr = (unsigned long)iov->iov_base; | 670 | unsigned long user_addr = (unsigned long)iov->iov_base; |
651 | size_t count = iov->iov_len; | 671 | size_t count = iov->iov_len; |
672 | struct rpc_message msg = { | ||
673 | .rpc_cred = ctx->cred, | ||
674 | }; | ||
652 | struct rpc_task_setup task_setup_data = { | 675 | struct rpc_task_setup task_setup_data = { |
653 | .rpc_client = NFS_CLIENT(inode), | 676 | .rpc_client = NFS_CLIENT(inode), |
677 | .rpc_message = &msg, | ||
654 | .callback_ops = &nfs_write_direct_ops, | 678 | .callback_ops = &nfs_write_direct_ops, |
655 | .flags = RPC_TASK_ASYNC, | 679 | .flags = RPC_TASK_ASYNC, |
656 | }; | 680 | }; |
@@ -696,20 +720,23 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq, | |||
696 | 720 | ||
697 | data->req = (struct nfs_page *) dreq; | 721 | data->req = (struct nfs_page *) dreq; |
698 | data->inode = inode; | 722 | data->inode = inode; |
699 | data->cred = ctx->cred; | 723 | data->cred = msg.rpc_cred; |
700 | data->args.fh = NFS_FH(inode); | 724 | data->args.fh = NFS_FH(inode); |
701 | data->args.context = ctx; | 725 | data->args.context = ctx; |
702 | data->args.offset = pos; | 726 | data->args.offset = pos; |
703 | data->args.pgbase = pgbase; | 727 | data->args.pgbase = pgbase; |
704 | data->args.pages = data->pagevec; | 728 | data->args.pages = data->pagevec; |
705 | data->args.count = bytes; | 729 | data->args.count = bytes; |
730 | data->args.stable = sync; | ||
706 | data->res.fattr = &data->fattr; | 731 | data->res.fattr = &data->fattr; |
707 | data->res.count = bytes; | 732 | data->res.count = bytes; |
708 | data->res.verf = &data->verf; | 733 | data->res.verf = &data->verf; |
709 | 734 | ||
710 | task_setup_data.callback_data = data; | 735 | task_setup_data.callback_data = data; |
736 | msg.rpc_argp = &data->args; | ||
737 | msg.rpc_resp = &data->res; | ||
738 | NFS_PROTO(inode)->write_setup(data, &msg); | ||
711 | rpc_init_task(&data->task, &task_setup_data); | 739 | rpc_init_task(&data->task, &task_setup_data); |
712 | NFS_PROTO(inode)->write_setup(data, sync); | ||
713 | 740 | ||
714 | rpc_execute(&data->task); | 741 | rpc_execute(&data->task); |
715 | 742 | ||
@@ -782,7 +809,7 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov, | |||
782 | struct rpc_clnt *clnt = NFS_CLIENT(inode); | 809 | struct rpc_clnt *clnt = NFS_CLIENT(inode); |
783 | struct nfs_direct_req *dreq; | 810 | struct nfs_direct_req *dreq; |
784 | size_t wsize = NFS_SERVER(inode)->wsize; | 811 | size_t wsize = NFS_SERVER(inode)->wsize; |
785 | int sync = 0; | 812 | int sync = NFS_UNSTABLE; |
786 | 813 | ||
787 | dreq = nfs_direct_req_alloc(); | 814 | dreq = nfs_direct_req_alloc(); |
788 | if (!dreq) | 815 | if (!dreq) |
@@ -790,7 +817,7 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov, | |||
790 | nfs_alloc_commit_data(dreq); | 817 | nfs_alloc_commit_data(dreq); |
791 | 818 | ||
792 | if (dreq->commit_data == NULL || count < wsize) | 819 | if (dreq->commit_data == NULL || count < wsize) |
793 | sync = FLUSH_STABLE; | 820 | sync = NFS_FILE_SYNC; |
794 | 821 | ||
795 | dreq->inode = inode; | 822 | dreq->inode = inode; |
796 | dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp)); | 823 | dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp)); |