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.c124
1 files changed, 85 insertions, 39 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 3c9d16b4f80c..f8e165c7d5a6 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -188,12 +188,17 @@ static void nfs_direct_req_release(struct nfs_direct_req *dreq)
188static ssize_t nfs_direct_wait(struct nfs_direct_req *dreq) 188static ssize_t nfs_direct_wait(struct nfs_direct_req *dreq)
189{ 189{
190 ssize_t result = -EIOCBQUEUED; 190 ssize_t result = -EIOCBQUEUED;
191 struct rpc_clnt *clnt;
192 sigset_t oldset;
191 193
192 /* Async requests don't wait here */ 194 /* Async requests don't wait here */
193 if (dreq->iocb) 195 if (dreq->iocb)
194 goto out; 196 goto out;
195 197
198 clnt = NFS_CLIENT(dreq->inode);
199 rpc_clnt_sigmask(clnt, &oldset);
196 result = wait_for_completion_interruptible(&dreq->completion); 200 result = wait_for_completion_interruptible(&dreq->completion);
201 rpc_clnt_sigunmask(clnt, &oldset);
197 202
198 if (!result) 203 if (!result)
199 result = dreq->error; 204 result = dreq->error;
@@ -272,6 +277,16 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq,
272 unsigned long user_addr = (unsigned long)iov->iov_base; 277 unsigned long user_addr = (unsigned long)iov->iov_base;
273 size_t count = iov->iov_len; 278 size_t count = iov->iov_len;
274 size_t rsize = NFS_SERVER(inode)->rsize; 279 size_t rsize = NFS_SERVER(inode)->rsize;
280 struct rpc_task *task;
281 struct rpc_message msg = {
282 .rpc_cred = ctx->cred,
283 };
284 struct rpc_task_setup task_setup_data = {
285 .rpc_client = NFS_CLIENT(inode),
286 .rpc_message = &msg,
287 .callback_ops = &nfs_read_direct_ops,
288 .flags = RPC_TASK_ASYNC,
289 };
275 unsigned int pgbase; 290 unsigned int pgbase;
276 int result; 291 int result;
277 ssize_t started = 0; 292 ssize_t started = 0;
@@ -311,7 +326,7 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq,
311 326
312 data->req = (struct nfs_page *) dreq; 327 data->req = (struct nfs_page *) dreq;
313 data->inode = inode; 328 data->inode = inode;
314 data->cred = ctx->cred; 329 data->cred = msg.rpc_cred;
315 data->args.fh = NFS_FH(inode); 330 data->args.fh = NFS_FH(inode);
316 data->args.context = ctx; 331 data->args.context = ctx;
317 data->args.offset = pos; 332 data->args.offset = pos;
@@ -321,14 +336,16 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq,
321 data->res.fattr = &data->fattr; 336 data->res.fattr = &data->fattr;
322 data->res.eof = 0; 337 data->res.eof = 0;
323 data->res.count = bytes; 338 data->res.count = bytes;
339 msg.rpc_argp = &data->args;
340 msg.rpc_resp = &data->res;
324 341
325 rpc_init_task(&data->task, NFS_CLIENT(inode), RPC_TASK_ASYNC, 342 task_setup_data.task = &data->task;
326 &nfs_read_direct_ops, data); 343 task_setup_data.callback_data = data;
327 NFS_PROTO(inode)->read_setup(data); 344 NFS_PROTO(inode)->read_setup(data, &msg);
328
329 data->task.tk_cookie = (unsigned long) inode;
330 345
331 rpc_execute(&data->task); 346 task = rpc_run_task(&task_setup_data);
347 if (!IS_ERR(task))
348 rpc_put_task(task);
332 349
333 dprintk("NFS: %5u initiated direct read call " 350 dprintk("NFS: %5u initiated direct read call "
334 "(req %s/%Ld, %zu bytes @ offset %Lu)\n", 351 "(req %s/%Ld, %zu bytes @ offset %Lu)\n",
@@ -391,9 +408,7 @@ static ssize_t nfs_direct_read(struct kiocb *iocb, const struct iovec *iov,
391 unsigned long nr_segs, loff_t pos) 408 unsigned long nr_segs, loff_t pos)
392{ 409{
393 ssize_t result = 0; 410 ssize_t result = 0;
394 sigset_t oldset;
395 struct inode *inode = iocb->ki_filp->f_mapping->host; 411 struct inode *inode = iocb->ki_filp->f_mapping->host;
396 struct rpc_clnt *clnt = NFS_CLIENT(inode);
397 struct nfs_direct_req *dreq; 412 struct nfs_direct_req *dreq;
398 413
399 dreq = nfs_direct_req_alloc(); 414 dreq = nfs_direct_req_alloc();
@@ -405,11 +420,9 @@ static ssize_t nfs_direct_read(struct kiocb *iocb, const struct iovec *iov,
405 if (!is_sync_kiocb(iocb)) 420 if (!is_sync_kiocb(iocb))
406 dreq->iocb = iocb; 421 dreq->iocb = iocb;
407 422
408 rpc_clnt_sigmask(clnt, &oldset);
409 result = nfs_direct_read_schedule_iovec(dreq, iov, nr_segs, pos); 423 result = nfs_direct_read_schedule_iovec(dreq, iov, nr_segs, pos);
410 if (!result) 424 if (!result)
411 result = nfs_direct_wait(dreq); 425 result = nfs_direct_wait(dreq);
412 rpc_clnt_sigunmask(clnt, &oldset);
413 nfs_direct_req_release(dreq); 426 nfs_direct_req_release(dreq);
414 427
415 return result; 428 return result;
@@ -431,6 +444,15 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
431 struct inode *inode = dreq->inode; 444 struct inode *inode = dreq->inode;
432 struct list_head *p; 445 struct list_head *p;
433 struct nfs_write_data *data; 446 struct nfs_write_data *data;
447 struct rpc_task *task;
448 struct rpc_message msg = {
449 .rpc_cred = dreq->ctx->cred,
450 };
451 struct rpc_task_setup task_setup_data = {
452 .rpc_client = NFS_CLIENT(inode),
453 .callback_ops = &nfs_write_direct_ops,
454 .flags = RPC_TASK_ASYNC,
455 };
434 456
435 dreq->count = 0; 457 dreq->count = 0;
436 get_dreq(dreq); 458 get_dreq(dreq);
@@ -440,6 +462,9 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
440 462
441 get_dreq(dreq); 463 get_dreq(dreq);
442 464
465 /* Use stable writes */
466 data->args.stable = NFS_FILE_SYNC;
467
443 /* 468 /*
444 * Reset data->res. 469 * Reset data->res.
445 */ 470 */
@@ -451,17 +476,18 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
451 * Reuse data->task; data->args should not have changed 476 * Reuse data->task; data->args should not have changed
452 * since the original request was sent. 477 * since the original request was sent.
453 */ 478 */
454 rpc_init_task(&data->task, NFS_CLIENT(inode), RPC_TASK_ASYNC, 479 task_setup_data.task = &data->task;
455 &nfs_write_direct_ops, data); 480 task_setup_data.callback_data = data;
456 NFS_PROTO(inode)->write_setup(data, FLUSH_STABLE); 481 msg.rpc_argp = &data->args;
457 482 msg.rpc_resp = &data->res;
458 data->task.tk_priority = RPC_PRIORITY_NORMAL; 483 NFS_PROTO(inode)->write_setup(data, &msg);
459 data->task.tk_cookie = (unsigned long) inode;
460 484
461 /* 485 /*
462 * We're called via an RPC callback, so BKL is already held. 486 * We're called via an RPC callback, so BKL is already held.
463 */ 487 */
464 rpc_execute(&data->task); 488 task = rpc_run_task(&task_setup_data);
489 if (!IS_ERR(task))
490 rpc_put_task(task);
465 491
466 dprintk("NFS: %5u rescheduled direct write call (req %s/%Ld, %u bytes @ offset %Lu)\n", 492 dprintk("NFS: %5u rescheduled direct write call (req %s/%Ld, %u bytes @ offset %Lu)\n",
467 data->task.tk_pid, 493 data->task.tk_pid,
@@ -504,9 +530,23 @@ static const struct rpc_call_ops nfs_commit_direct_ops = {
504static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) 530static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
505{ 531{
506 struct nfs_write_data *data = dreq->commit_data; 532 struct nfs_write_data *data = dreq->commit_data;
533 struct rpc_task *task;
534 struct rpc_message msg = {
535 .rpc_argp = &data->args,
536 .rpc_resp = &data->res,
537 .rpc_cred = dreq->ctx->cred,
538 };
539 struct rpc_task_setup task_setup_data = {
540 .task = &data->task,
541 .rpc_client = NFS_CLIENT(dreq->inode),
542 .rpc_message = &msg,
543 .callback_ops = &nfs_commit_direct_ops,
544 .callback_data = data,
545 .flags = RPC_TASK_ASYNC,
546 };
507 547
508 data->inode = dreq->inode; 548 data->inode = dreq->inode;
509 data->cred = dreq->ctx->cred; 549 data->cred = msg.rpc_cred;
510 550
511 data->args.fh = NFS_FH(data->inode); 551 data->args.fh = NFS_FH(data->inode);
512 data->args.offset = 0; 552 data->args.offset = 0;
@@ -515,18 +555,16 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
515 data->res.fattr = &data->fattr; 555 data->res.fattr = &data->fattr;
516 data->res.verf = &data->verf; 556 data->res.verf = &data->verf;
517 557
518 rpc_init_task(&data->task, NFS_CLIENT(dreq->inode), RPC_TASK_ASYNC, 558 NFS_PROTO(data->inode)->commit_setup(data, &msg);
519 &nfs_commit_direct_ops, data);
520 NFS_PROTO(data->inode)->commit_setup(data, 0);
521 559
522 data->task.tk_priority = RPC_PRIORITY_NORMAL;
523 data->task.tk_cookie = (unsigned long)data->inode;
524 /* Note: task.tk_ops->rpc_release will free dreq->commit_data */ 560 /* Note: task.tk_ops->rpc_release will free dreq->commit_data */
525 dreq->commit_data = NULL; 561 dreq->commit_data = NULL;
526 562
527 dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid); 563 dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid);
528 564
529 rpc_execute(&data->task); 565 task = rpc_run_task(&task_setup_data);
566 if (!IS_ERR(task))
567 rpc_put_task(task);
530} 568}
531 569
532static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode *inode) 570static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode *inode)
@@ -641,6 +679,16 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq,
641 struct inode *inode = ctx->path.dentry->d_inode; 679 struct inode *inode = ctx->path.dentry->d_inode;
642 unsigned long user_addr = (unsigned long)iov->iov_base; 680 unsigned long user_addr = (unsigned long)iov->iov_base;
643 size_t count = iov->iov_len; 681 size_t count = iov->iov_len;
682 struct rpc_task *task;
683 struct rpc_message msg = {
684 .rpc_cred = ctx->cred,
685 };
686 struct rpc_task_setup task_setup_data = {
687 .rpc_client = NFS_CLIENT(inode),
688 .rpc_message = &msg,
689 .callback_ops = &nfs_write_direct_ops,
690 .flags = RPC_TASK_ASYNC,
691 };
644 size_t wsize = NFS_SERVER(inode)->wsize; 692 size_t wsize = NFS_SERVER(inode)->wsize;
645 unsigned int pgbase; 693 unsigned int pgbase;
646 int result; 694 int result;
@@ -683,25 +731,27 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq,
683 731
684 data->req = (struct nfs_page *) dreq; 732 data->req = (struct nfs_page *) dreq;
685 data->inode = inode; 733 data->inode = inode;
686 data->cred = ctx->cred; 734 data->cred = msg.rpc_cred;
687 data->args.fh = NFS_FH(inode); 735 data->args.fh = NFS_FH(inode);
688 data->args.context = ctx; 736 data->args.context = ctx;
689 data->args.offset = pos; 737 data->args.offset = pos;
690 data->args.pgbase = pgbase; 738 data->args.pgbase = pgbase;
691 data->args.pages = data->pagevec; 739 data->args.pages = data->pagevec;
692 data->args.count = bytes; 740 data->args.count = bytes;
741 data->args.stable = sync;
693 data->res.fattr = &data->fattr; 742 data->res.fattr = &data->fattr;
694 data->res.count = bytes; 743 data->res.count = bytes;
695 data->res.verf = &data->verf; 744 data->res.verf = &data->verf;
696 745
697 rpc_init_task(&data->task, NFS_CLIENT(inode), RPC_TASK_ASYNC, 746 task_setup_data.task = &data->task;
698 &nfs_write_direct_ops, data); 747 task_setup_data.callback_data = data;
699 NFS_PROTO(inode)->write_setup(data, sync); 748 msg.rpc_argp = &data->args;
700 749 msg.rpc_resp = &data->res;
701 data->task.tk_priority = RPC_PRIORITY_NORMAL; 750 NFS_PROTO(inode)->write_setup(data, &msg);
702 data->task.tk_cookie = (unsigned long) inode;
703 751
704 rpc_execute(&data->task); 752 task = rpc_run_task(&task_setup_data);
753 if (!IS_ERR(task))
754 rpc_put_task(task);
705 755
706 dprintk("NFS: %5u initiated direct write call " 756 dprintk("NFS: %5u initiated direct write call "
707 "(req %s/%Ld, %zu bytes @ offset %Lu)\n", 757 "(req %s/%Ld, %zu bytes @ offset %Lu)\n",
@@ -767,12 +817,10 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov,
767 size_t count) 817 size_t count)
768{ 818{
769 ssize_t result = 0; 819 ssize_t result = 0;
770 sigset_t oldset;
771 struct inode *inode = iocb->ki_filp->f_mapping->host; 820 struct inode *inode = iocb->ki_filp->f_mapping->host;
772 struct rpc_clnt *clnt = NFS_CLIENT(inode);
773 struct nfs_direct_req *dreq; 821 struct nfs_direct_req *dreq;
774 size_t wsize = NFS_SERVER(inode)->wsize; 822 size_t wsize = NFS_SERVER(inode)->wsize;
775 int sync = 0; 823 int sync = NFS_UNSTABLE;
776 824
777 dreq = nfs_direct_req_alloc(); 825 dreq = nfs_direct_req_alloc();
778 if (!dreq) 826 if (!dreq)
@@ -780,18 +828,16 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov,
780 nfs_alloc_commit_data(dreq); 828 nfs_alloc_commit_data(dreq);
781 829
782 if (dreq->commit_data == NULL || count < wsize) 830 if (dreq->commit_data == NULL || count < wsize)
783 sync = FLUSH_STABLE; 831 sync = NFS_FILE_SYNC;
784 832
785 dreq->inode = inode; 833 dreq->inode = inode;
786 dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp)); 834 dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp));
787 if (!is_sync_kiocb(iocb)) 835 if (!is_sync_kiocb(iocb))
788 dreq->iocb = iocb; 836 dreq->iocb = iocb;
789 837
790 rpc_clnt_sigmask(clnt, &oldset);
791 result = nfs_direct_write_schedule_iovec(dreq, iov, nr_segs, pos, sync); 838 result = nfs_direct_write_schedule_iovec(dreq, iov, nr_segs, pos, sync);
792 if (!result) 839 if (!result)
793 result = nfs_direct_wait(dreq); 840 result = nfs_direct_wait(dreq);
794 rpc_clnt_sigunmask(clnt, &oldset);
795 nfs_direct_req_release(dreq); 841 nfs_direct_req_release(dreq);
796 842
797 return result; 843 return result;