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.c113
1 files changed, 80 insertions, 33 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 7b994b2fa593..16844f98f50e 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -272,6 +272,16 @@ 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_task *task;
276 struct rpc_message msg = {
277 .rpc_cred = ctx->cred,
278 };
279 struct rpc_task_setup task_setup_data = {
280 .rpc_client = NFS_CLIENT(inode),
281 .rpc_message = &msg,
282 .callback_ops = &nfs_read_direct_ops,
283 .flags = RPC_TASK_ASYNC,
284 };
275 unsigned int pgbase; 285 unsigned int pgbase;
276 int result; 286 int result;
277 ssize_t started = 0; 287 ssize_t started = 0;
@@ -311,7 +321,7 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq,
311 321
312 data->req = (struct nfs_page *) dreq; 322 data->req = (struct nfs_page *) dreq;
313 data->inode = inode; 323 data->inode = inode;
314 data->cred = ctx->cred; 324 data->cred = msg.rpc_cred;
315 data->args.fh = NFS_FH(inode); 325 data->args.fh = NFS_FH(inode);
316 data->args.context = ctx; 326 data->args.context = ctx;
317 data->args.offset = pos; 327 data->args.offset = pos;
@@ -321,14 +331,16 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq,
321 data->res.fattr = &data->fattr; 331 data->res.fattr = &data->fattr;
322 data->res.eof = 0; 332 data->res.eof = 0;
323 data->res.count = bytes; 333 data->res.count = bytes;
334 msg.rpc_argp = &data->args;
335 msg.rpc_resp = &data->res;
324 336
325 rpc_init_task(&data->task, NFS_CLIENT(inode), RPC_TASK_ASYNC, 337 task_setup_data.task = &data->task;
326 &nfs_read_direct_ops, data); 338 task_setup_data.callback_data = data;
327 NFS_PROTO(inode)->read_setup(data); 339 NFS_PROTO(inode)->read_setup(data, &msg);
328 340
329 data->task.tk_cookie = (unsigned long) inode; 341 task = rpc_run_task(&task_setup_data);
330 342 if (!IS_ERR(task))
331 rpc_execute(&data->task); 343 rpc_put_task(task);
332 344
333 dprintk("NFS: %5u initiated direct read call " 345 dprintk("NFS: %5u initiated direct read call "
334 "(req %s/%Ld, %zu bytes @ offset %Lu)\n", 346 "(req %s/%Ld, %zu bytes @ offset %Lu)\n",
@@ -427,6 +439,15 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
427 struct inode *inode = dreq->inode; 439 struct inode *inode = dreq->inode;
428 struct list_head *p; 440 struct list_head *p;
429 struct nfs_write_data *data; 441 struct nfs_write_data *data;
442 struct rpc_task *task;
443 struct rpc_message msg = {
444 .rpc_cred = dreq->ctx->cred,
445 };
446 struct rpc_task_setup task_setup_data = {
447 .rpc_client = NFS_CLIENT(inode),
448 .callback_ops = &nfs_write_direct_ops,
449 .flags = RPC_TASK_ASYNC,
450 };
430 451
431 dreq->count = 0; 452 dreq->count = 0;
432 get_dreq(dreq); 453 get_dreq(dreq);
@@ -436,6 +457,9 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
436 457
437 get_dreq(dreq); 458 get_dreq(dreq);
438 459
460 /* Use stable writes */
461 data->args.stable = NFS_FILE_SYNC;
462
439 /* 463 /*
440 * Reset data->res. 464 * Reset data->res.
441 */ 465 */
@@ -447,17 +471,18 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
447 * Reuse data->task; data->args should not have changed 471 * Reuse data->task; data->args should not have changed
448 * since the original request was sent. 472 * since the original request was sent.
449 */ 473 */
450 rpc_init_task(&data->task, NFS_CLIENT(inode), RPC_TASK_ASYNC, 474 task_setup_data.task = &data->task;
451 &nfs_write_direct_ops, data); 475 task_setup_data.callback_data = data;
452 NFS_PROTO(inode)->write_setup(data, FLUSH_STABLE); 476 msg.rpc_argp = &data->args;
453 477 msg.rpc_resp = &data->res;
454 data->task.tk_priority = RPC_PRIORITY_NORMAL; 478 NFS_PROTO(inode)->write_setup(data, &msg);
455 data->task.tk_cookie = (unsigned long) inode;
456 479
457 /* 480 /*
458 * 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.
459 */ 482 */
460 rpc_execute(&data->task); 483 task = rpc_run_task(&task_setup_data);
484 if (!IS_ERR(task))
485 rpc_put_task(task);
461 486
462 dprintk("NFS: %5u rescheduled direct write call (req %s/%Ld, %u bytes @ offset %Lu)\n", 487 dprintk("NFS: %5u rescheduled direct write call (req %s/%Ld, %u bytes @ offset %Lu)\n",
463 data->task.tk_pid, 488 data->task.tk_pid,
@@ -500,9 +525,23 @@ static const struct rpc_call_ops nfs_commit_direct_ops = {
500static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) 525static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
501{ 526{
502 struct nfs_write_data *data = dreq->commit_data; 527 struct nfs_write_data *data = dreq->commit_data;
528 struct rpc_task *task;
529 struct rpc_message msg = {
530 .rpc_argp = &data->args,
531 .rpc_resp = &data->res,
532 .rpc_cred = dreq->ctx->cred,
533 };
534 struct rpc_task_setup task_setup_data = {
535 .task = &data->task,
536 .rpc_client = NFS_CLIENT(dreq->inode),
537 .rpc_message = &msg,
538 .callback_ops = &nfs_commit_direct_ops,
539 .callback_data = data,
540 .flags = RPC_TASK_ASYNC,
541 };
503 542
504 data->inode = dreq->inode; 543 data->inode = dreq->inode;
505 data->cred = dreq->ctx->cred; 544 data->cred = msg.rpc_cred;
506 545
507 data->args.fh = NFS_FH(data->inode); 546 data->args.fh = NFS_FH(data->inode);
508 data->args.offset = 0; 547 data->args.offset = 0;
@@ -511,18 +550,16 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
511 data->res.fattr = &data->fattr; 550 data->res.fattr = &data->fattr;
512 data->res.verf = &data->verf; 551 data->res.verf = &data->verf;
513 552
514 rpc_init_task(&data->task, NFS_CLIENT(dreq->inode), RPC_TASK_ASYNC, 553 NFS_PROTO(data->inode)->commit_setup(data, &msg);
515 &nfs_commit_direct_ops, data);
516 NFS_PROTO(data->inode)->commit_setup(data, 0);
517 554
518 data->task.tk_priority = RPC_PRIORITY_NORMAL;
519 data->task.tk_cookie = (unsigned long)data->inode;
520 /* Note: task.tk_ops->rpc_release will free dreq->commit_data */ 555 /* Note: task.tk_ops->rpc_release will free dreq->commit_data */
521 dreq->commit_data = NULL; 556 dreq->commit_data = NULL;
522 557
523 dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid); 558 dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid);
524 559
525 rpc_execute(&data->task); 560 task = rpc_run_task(&task_setup_data);
561 if (!IS_ERR(task))
562 rpc_put_task(task);
526} 563}
527 564
528static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode *inode) 565static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode *inode)
@@ -637,6 +674,16 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq,
637 struct inode *inode = ctx->path.dentry->d_inode; 674 struct inode *inode = ctx->path.dentry->d_inode;
638 unsigned long user_addr = (unsigned long)iov->iov_base; 675 unsigned long user_addr = (unsigned long)iov->iov_base;
639 size_t count = iov->iov_len; 676 size_t count = iov->iov_len;
677 struct rpc_task *task;
678 struct rpc_message msg = {
679 .rpc_cred = ctx->cred,
680 };
681 struct rpc_task_setup task_setup_data = {
682 .rpc_client = NFS_CLIENT(inode),
683 .rpc_message = &msg,
684 .callback_ops = &nfs_write_direct_ops,
685 .flags = RPC_TASK_ASYNC,
686 };
640 size_t wsize = NFS_SERVER(inode)->wsize; 687 size_t wsize = NFS_SERVER(inode)->wsize;
641 unsigned int pgbase; 688 unsigned int pgbase;
642 int result; 689 int result;
@@ -679,25 +726,27 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq,
679 726
680 data->req = (struct nfs_page *) dreq; 727 data->req = (struct nfs_page *) dreq;
681 data->inode = inode; 728 data->inode = inode;
682 data->cred = ctx->cred; 729 data->cred = msg.rpc_cred;
683 data->args.fh = NFS_FH(inode); 730 data->args.fh = NFS_FH(inode);
684 data->args.context = ctx; 731 data->args.context = ctx;
685 data->args.offset = pos; 732 data->args.offset = pos;
686 data->args.pgbase = pgbase; 733 data->args.pgbase = pgbase;
687 data->args.pages = data->pagevec; 734 data->args.pages = data->pagevec;
688 data->args.count = bytes; 735 data->args.count = bytes;
736 data->args.stable = sync;
689 data->res.fattr = &data->fattr; 737 data->res.fattr = &data->fattr;
690 data->res.count = bytes; 738 data->res.count = bytes;
691 data->res.verf = &data->verf; 739 data->res.verf = &data->verf;
692 740
693 rpc_init_task(&data->task, NFS_CLIENT(inode), RPC_TASK_ASYNC, 741 task_setup_data.task = &data->task;
694 &nfs_write_direct_ops, data); 742 task_setup_data.callback_data = data;
695 NFS_PROTO(inode)->write_setup(data, sync); 743 msg.rpc_argp = &data->args;
744 msg.rpc_resp = &data->res;
745 NFS_PROTO(inode)->write_setup(data, &msg);
696 746
697 data->task.tk_priority = RPC_PRIORITY_NORMAL; 747 task = rpc_run_task(&task_setup_data);
698 data->task.tk_cookie = (unsigned long) inode; 748 if (!IS_ERR(task))
699 749 rpc_put_task(task);
700 rpc_execute(&data->task);
701 750
702 dprintk("NFS: %5u initiated direct write call " 751 dprintk("NFS: %5u initiated direct write call "
703 "(req %s/%Ld, %zu bytes @ offset %Lu)\n", 752 "(req %s/%Ld, %zu bytes @ offset %Lu)\n",
@@ -766,7 +815,7 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov,
766 struct inode *inode = iocb->ki_filp->f_mapping->host; 815 struct inode *inode = iocb->ki_filp->f_mapping->host;
767 struct nfs_direct_req *dreq; 816 struct nfs_direct_req *dreq;
768 size_t wsize = NFS_SERVER(inode)->wsize; 817 size_t wsize = NFS_SERVER(inode)->wsize;
769 int sync = 0; 818 int sync = NFS_UNSTABLE;
770 819
771 dreq = nfs_direct_req_alloc(); 820 dreq = nfs_direct_req_alloc();
772 if (!dreq) 821 if (!dreq)
@@ -774,7 +823,7 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov,
774 nfs_alloc_commit_data(dreq); 823 nfs_alloc_commit_data(dreq);
775 824
776 if (dreq->commit_data == NULL || count < wsize) 825 if (dreq->commit_data == NULL || count < wsize)
777 sync = FLUSH_STABLE; 826 sync = NFS_FILE_SYNC;
778 827
779 dreq->inode = inode; 828 dreq->inode = inode;
780 dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp)); 829 dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp));
@@ -886,8 +935,6 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov,
886 retval = generic_write_checks(file, &pos, &count, 0); 935 retval = generic_write_checks(file, &pos, &count, 0);
887 if (retval) 936 if (retval)
888 goto out; 937 goto out;
889 if (!count)
890 goto out; /* return 0 */
891 938
892 retval = -EINVAL; 939 retval = -EINVAL;
893 if ((ssize_t) count < 0) 940 if ((ssize_t) count < 0)