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.c261
1 files changed, 178 insertions, 83 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index afcab007a22b..16844f98f50e 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -193,7 +193,7 @@ static ssize_t nfs_direct_wait(struct nfs_direct_req *dreq)
193 if (dreq->iocb) 193 if (dreq->iocb)
194 goto out; 194 goto out;
195 195
196 result = wait_for_completion_interruptible(&dreq->completion); 196 result = wait_for_completion_killable(&dreq->completion);
197 197
198 if (!result) 198 if (!result)
199 result = dreq->error; 199 result = dreq->error;
@@ -263,17 +263,29 @@ static const struct rpc_call_ops nfs_read_direct_ops = {
263 * handled automatically by nfs_direct_read_result(). Otherwise, if 263 * handled automatically by nfs_direct_read_result(). Otherwise, if
264 * no requests have been sent, just return an error. 264 * no requests have been sent, just return an error.
265 */ 265 */
266static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned long user_addr, size_t count, loff_t pos) 266static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq,
267 const struct iovec *iov,
268 loff_t pos)
267{ 269{
268 struct nfs_open_context *ctx = dreq->ctx; 270 struct nfs_open_context *ctx = dreq->ctx;
269 struct inode *inode = ctx->path.dentry->d_inode; 271 struct inode *inode = ctx->path.dentry->d_inode;
272 unsigned long user_addr = (unsigned long)iov->iov_base;
273 size_t count = iov->iov_len;
270 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 };
271 unsigned int pgbase; 285 unsigned int pgbase;
272 int result; 286 int result;
273 ssize_t started = 0; 287 ssize_t started = 0;
274 288
275 get_dreq(dreq);
276
277 do { 289 do {
278 struct nfs_read_data *data; 290 struct nfs_read_data *data;
279 size_t bytes; 291 size_t bytes;
@@ -309,7 +321,7 @@ static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned lo
309 321
310 data->req = (struct nfs_page *) dreq; 322 data->req = (struct nfs_page *) dreq;
311 data->inode = inode; 323 data->inode = inode;
312 data->cred = ctx->cred; 324 data->cred = msg.rpc_cred;
313 data->args.fh = NFS_FH(inode); 325 data->args.fh = NFS_FH(inode);
314 data->args.context = ctx; 326 data->args.context = ctx;
315 data->args.offset = pos; 327 data->args.offset = pos;
@@ -319,14 +331,16 @@ static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned lo
319 data->res.fattr = &data->fattr; 331 data->res.fattr = &data->fattr;
320 data->res.eof = 0; 332 data->res.eof = 0;
321 data->res.count = bytes; 333 data->res.count = bytes;
334 msg.rpc_argp = &data->args;
335 msg.rpc_resp = &data->res;
322 336
323 rpc_init_task(&data->task, NFS_CLIENT(inode), RPC_TASK_ASYNC, 337 task_setup_data.task = &data->task;
324 &nfs_read_direct_ops, data); 338 task_setup_data.callback_data = data;
325 NFS_PROTO(inode)->read_setup(data); 339 NFS_PROTO(inode)->read_setup(data, &msg);
326 340
327 data->task.tk_cookie = (unsigned long) inode; 341 task = rpc_run_task(&task_setup_data);
328 342 if (!IS_ERR(task))
329 rpc_execute(&data->task); 343 rpc_put_task(task);
330 344
331 dprintk("NFS: %5u initiated direct read call " 345 dprintk("NFS: %5u initiated direct read call "
332 "(req %s/%Ld, %zu bytes @ offset %Lu)\n", 346 "(req %s/%Ld, %zu bytes @ offset %Lu)\n",
@@ -347,20 +361,49 @@ static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned lo
347 count -= bytes; 361 count -= bytes;
348 } while (count != 0); 362 } while (count != 0);
349 363
364 if (started)
365 return started;
366 return result < 0 ? (ssize_t) result : -EFAULT;
367}
368
369static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,
370 const struct iovec *iov,
371 unsigned long nr_segs,
372 loff_t pos)
373{
374 ssize_t result = -EINVAL;
375 size_t requested_bytes = 0;
376 unsigned long seg;
377
378 get_dreq(dreq);
379
380 for (seg = 0; seg < nr_segs; seg++) {
381 const struct iovec *vec = &iov[seg];
382 result = nfs_direct_read_schedule_segment(dreq, vec, pos);
383 if (result < 0)
384 break;
385 requested_bytes += result;
386 if ((size_t)result < vec->iov_len)
387 break;
388 pos += vec->iov_len;
389 }
390
350 if (put_dreq(dreq)) 391 if (put_dreq(dreq))
351 nfs_direct_complete(dreq); 392 nfs_direct_complete(dreq);
352 393
353 if (started) 394 if (requested_bytes != 0)
354 return 0; 395 return 0;
355 return result < 0 ? (ssize_t) result : -EFAULT; 396
397 if (result < 0)
398 return result;
399 return -EIO;
356} 400}
357 401
358static ssize_t nfs_direct_read(struct kiocb *iocb, unsigned long user_addr, size_t count, loff_t pos) 402static ssize_t nfs_direct_read(struct kiocb *iocb, const struct iovec *iov,
403 unsigned long nr_segs, loff_t pos)
359{ 404{
360 ssize_t result = 0; 405 ssize_t result = 0;
361 sigset_t oldset;
362 struct inode *inode = iocb->ki_filp->f_mapping->host; 406 struct inode *inode = iocb->ki_filp->f_mapping->host;
363 struct rpc_clnt *clnt = NFS_CLIENT(inode);
364 struct nfs_direct_req *dreq; 407 struct nfs_direct_req *dreq;
365 408
366 dreq = nfs_direct_req_alloc(); 409 dreq = nfs_direct_req_alloc();
@@ -372,12 +415,9 @@ static ssize_t nfs_direct_read(struct kiocb *iocb, unsigned long user_addr, size
372 if (!is_sync_kiocb(iocb)) 415 if (!is_sync_kiocb(iocb))
373 dreq->iocb = iocb; 416 dreq->iocb = iocb;
374 417
375 nfs_add_stats(inode, NFSIOS_DIRECTREADBYTES, count); 418 result = nfs_direct_read_schedule_iovec(dreq, iov, nr_segs, pos);
376 rpc_clnt_sigmask(clnt, &oldset);
377 result = nfs_direct_read_schedule(dreq, user_addr, count, pos);
378 if (!result) 419 if (!result)
379 result = nfs_direct_wait(dreq); 420 result = nfs_direct_wait(dreq);
380 rpc_clnt_sigunmask(clnt, &oldset);
381 nfs_direct_req_release(dreq); 421 nfs_direct_req_release(dreq);
382 422
383 return result; 423 return result;
@@ -399,6 +439,15 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
399 struct inode *inode = dreq->inode; 439 struct inode *inode = dreq->inode;
400 struct list_head *p; 440 struct list_head *p;
401 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 };
402 451
403 dreq->count = 0; 452 dreq->count = 0;
404 get_dreq(dreq); 453 get_dreq(dreq);
@@ -408,6 +457,9 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
408 457
409 get_dreq(dreq); 458 get_dreq(dreq);
410 459
460 /* Use stable writes */
461 data->args.stable = NFS_FILE_SYNC;
462
411 /* 463 /*
412 * Reset data->res. 464 * Reset data->res.
413 */ 465 */
@@ -419,17 +471,18 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
419 * Reuse data->task; data->args should not have changed 471 * Reuse data->task; data->args should not have changed
420 * since the original request was sent. 472 * since the original request was sent.
421 */ 473 */
422 rpc_init_task(&data->task, NFS_CLIENT(inode), RPC_TASK_ASYNC, 474 task_setup_data.task = &data->task;
423 &nfs_write_direct_ops, data); 475 task_setup_data.callback_data = data;
424 NFS_PROTO(inode)->write_setup(data, FLUSH_STABLE); 476 msg.rpc_argp = &data->args;
425 477 msg.rpc_resp = &data->res;
426 data->task.tk_priority = RPC_PRIORITY_NORMAL; 478 NFS_PROTO(inode)->write_setup(data, &msg);
427 data->task.tk_cookie = (unsigned long) inode;
428 479
429 /* 480 /*
430 * 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.
431 */ 482 */
432 rpc_execute(&data->task); 483 task = rpc_run_task(&task_setup_data);
484 if (!IS_ERR(task))
485 rpc_put_task(task);
433 486
434 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",
435 data->task.tk_pid, 488 data->task.tk_pid,
@@ -472,9 +525,23 @@ static const struct rpc_call_ops nfs_commit_direct_ops = {
472static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) 525static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
473{ 526{
474 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 };
475 542
476 data->inode = dreq->inode; 543 data->inode = dreq->inode;
477 data->cred = dreq->ctx->cred; 544 data->cred = msg.rpc_cred;
478 545
479 data->args.fh = NFS_FH(data->inode); 546 data->args.fh = NFS_FH(data->inode);
480 data->args.offset = 0; 547 data->args.offset = 0;
@@ -483,18 +550,16 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
483 data->res.fattr = &data->fattr; 550 data->res.fattr = &data->fattr;
484 data->res.verf = &data->verf; 551 data->res.verf = &data->verf;
485 552
486 rpc_init_task(&data->task, NFS_CLIENT(dreq->inode), RPC_TASK_ASYNC, 553 NFS_PROTO(data->inode)->commit_setup(data, &msg);
487 &nfs_commit_direct_ops, data);
488 NFS_PROTO(data->inode)->commit_setup(data, 0);
489 554
490 data->task.tk_priority = RPC_PRIORITY_NORMAL;
491 data->task.tk_cookie = (unsigned long)data->inode;
492 /* Note: task.tk_ops->rpc_release will free dreq->commit_data */ 555 /* Note: task.tk_ops->rpc_release will free dreq->commit_data */
493 dreq->commit_data = NULL; 556 dreq->commit_data = NULL;
494 557
495 dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid); 558 dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid);
496 559
497 rpc_execute(&data->task); 560 task = rpc_run_task(&task_setup_data);
561 if (!IS_ERR(task))
562 rpc_put_task(task);
498} 563}
499 564
500static 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)
@@ -601,17 +666,29 @@ static const struct rpc_call_ops nfs_write_direct_ops = {
601 * handled automatically by nfs_direct_write_result(). Otherwise, if 666 * handled automatically by nfs_direct_write_result(). Otherwise, if
602 * no requests have been sent, just return an error. 667 * no requests have been sent, just return an error.
603 */ 668 */
604static ssize_t nfs_direct_write_schedule(struct nfs_direct_req *dreq, unsigned long user_addr, size_t count, loff_t pos, int sync) 669static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq,
670 const struct iovec *iov,
671 loff_t pos, int sync)
605{ 672{
606 struct nfs_open_context *ctx = dreq->ctx; 673 struct nfs_open_context *ctx = dreq->ctx;
607 struct inode *inode = ctx->path.dentry->d_inode; 674 struct inode *inode = ctx->path.dentry->d_inode;
675 unsigned long user_addr = (unsigned long)iov->iov_base;
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 };
608 size_t wsize = NFS_SERVER(inode)->wsize; 687 size_t wsize = NFS_SERVER(inode)->wsize;
609 unsigned int pgbase; 688 unsigned int pgbase;
610 int result; 689 int result;
611 ssize_t started = 0; 690 ssize_t started = 0;
612 691
613 get_dreq(dreq);
614
615 do { 692 do {
616 struct nfs_write_data *data; 693 struct nfs_write_data *data;
617 size_t bytes; 694 size_t bytes;
@@ -649,25 +726,27 @@ static ssize_t nfs_direct_write_schedule(struct nfs_direct_req *dreq, unsigned l
649 726
650 data->req = (struct nfs_page *) dreq; 727 data->req = (struct nfs_page *) dreq;
651 data->inode = inode; 728 data->inode = inode;
652 data->cred = ctx->cred; 729 data->cred = msg.rpc_cred;
653 data->args.fh = NFS_FH(inode); 730 data->args.fh = NFS_FH(inode);
654 data->args.context = ctx; 731 data->args.context = ctx;
655 data->args.offset = pos; 732 data->args.offset = pos;
656 data->args.pgbase = pgbase; 733 data->args.pgbase = pgbase;
657 data->args.pages = data->pagevec; 734 data->args.pages = data->pagevec;
658 data->args.count = bytes; 735 data->args.count = bytes;
736 data->args.stable = sync;
659 data->res.fattr = &data->fattr; 737 data->res.fattr = &data->fattr;
660 data->res.count = bytes; 738 data->res.count = bytes;
661 data->res.verf = &data->verf; 739 data->res.verf = &data->verf;
662 740
663 rpc_init_task(&data->task, NFS_CLIENT(inode), RPC_TASK_ASYNC, 741 task_setup_data.task = &data->task;
664 &nfs_write_direct_ops, data); 742 task_setup_data.callback_data = data;
665 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);
666 746
667 data->task.tk_priority = RPC_PRIORITY_NORMAL; 747 task = rpc_run_task(&task_setup_data);
668 data->task.tk_cookie = (unsigned long) inode; 748 if (!IS_ERR(task))
669 749 rpc_put_task(task);
670 rpc_execute(&data->task);
671 750
672 dprintk("NFS: %5u initiated direct write call " 751 dprintk("NFS: %5u initiated direct write call "
673 "(req %s/%Ld, %zu bytes @ offset %Lu)\n", 752 "(req %s/%Ld, %zu bytes @ offset %Lu)\n",
@@ -689,23 +768,54 @@ static ssize_t nfs_direct_write_schedule(struct nfs_direct_req *dreq, unsigned l
689 count -= bytes; 768 count -= bytes;
690 } while (count != 0); 769 } while (count != 0);
691 770
771 if (started)
772 return started;
773 return result < 0 ? (ssize_t) result : -EFAULT;
774}
775
776static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
777 const struct iovec *iov,
778 unsigned long nr_segs,
779 loff_t pos, int sync)
780{
781 ssize_t result = 0;
782 size_t requested_bytes = 0;
783 unsigned long seg;
784
785 get_dreq(dreq);
786
787 for (seg = 0; seg < nr_segs; seg++) {
788 const struct iovec *vec = &iov[seg];
789 result = nfs_direct_write_schedule_segment(dreq, vec,
790 pos, sync);
791 if (result < 0)
792 break;
793 requested_bytes += result;
794 if ((size_t)result < vec->iov_len)
795 break;
796 pos += vec->iov_len;
797 }
798
692 if (put_dreq(dreq)) 799 if (put_dreq(dreq))
693 nfs_direct_write_complete(dreq, inode); 800 nfs_direct_write_complete(dreq, dreq->inode);
694 801
695 if (started) 802 if (requested_bytes != 0)
696 return 0; 803 return 0;
697 return result < 0 ? (ssize_t) result : -EFAULT; 804
805 if (result < 0)
806 return result;
807 return -EIO;
698} 808}
699 809
700static ssize_t nfs_direct_write(struct kiocb *iocb, unsigned long user_addr, size_t count, loff_t pos) 810static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov,
811 unsigned long nr_segs, loff_t pos,
812 size_t count)
701{ 813{
702 ssize_t result = 0; 814 ssize_t result = 0;
703 sigset_t oldset;
704 struct inode *inode = iocb->ki_filp->f_mapping->host; 815 struct inode *inode = iocb->ki_filp->f_mapping->host;
705 struct rpc_clnt *clnt = NFS_CLIENT(inode);
706 struct nfs_direct_req *dreq; 816 struct nfs_direct_req *dreq;
707 size_t wsize = NFS_SERVER(inode)->wsize; 817 size_t wsize = NFS_SERVER(inode)->wsize;
708 int sync = 0; 818 int sync = NFS_UNSTABLE;
709 819
710 dreq = nfs_direct_req_alloc(); 820 dreq = nfs_direct_req_alloc();
711 if (!dreq) 821 if (!dreq)
@@ -713,20 +823,16 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, unsigned long user_addr, siz
713 nfs_alloc_commit_data(dreq); 823 nfs_alloc_commit_data(dreq);
714 824
715 if (dreq->commit_data == NULL || count < wsize) 825 if (dreq->commit_data == NULL || count < wsize)
716 sync = FLUSH_STABLE; 826 sync = NFS_FILE_SYNC;
717 827
718 dreq->inode = inode; 828 dreq->inode = inode;
719 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));
720 if (!is_sync_kiocb(iocb)) 830 if (!is_sync_kiocb(iocb))
721 dreq->iocb = iocb; 831 dreq->iocb = iocb;
722 832
723 nfs_add_stats(inode, NFSIOS_DIRECTWRITTENBYTES, count); 833 result = nfs_direct_write_schedule_iovec(dreq, iov, nr_segs, pos, sync);
724
725 rpc_clnt_sigmask(clnt, &oldset);
726 result = nfs_direct_write_schedule(dreq, user_addr, count, pos, sync);
727 if (!result) 834 if (!result)
728 result = nfs_direct_wait(dreq); 835 result = nfs_direct_wait(dreq);
729 rpc_clnt_sigunmask(clnt, &oldset);
730 nfs_direct_req_release(dreq); 836 nfs_direct_req_release(dreq);
731 837
732 return result; 838 return result;
@@ -759,21 +865,16 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, const struct iovec *iov,
759 ssize_t retval = -EINVAL; 865 ssize_t retval = -EINVAL;
760 struct file *file = iocb->ki_filp; 866 struct file *file = iocb->ki_filp;
761 struct address_space *mapping = file->f_mapping; 867 struct address_space *mapping = file->f_mapping;
762 /* XXX: temporary */ 868 size_t count;
763 const char __user *buf = iov[0].iov_base;
764 size_t count = iov[0].iov_len;
765 869
766 dprintk("nfs: direct read(%s/%s, %lu@%Ld)\n", 870 count = iov_length(iov, nr_segs);
871 nfs_add_stats(mapping->host, NFSIOS_DIRECTREADBYTES, count);
872
873 dprintk("nfs: direct read(%s/%s, %zd@%Ld)\n",
767 file->f_path.dentry->d_parent->d_name.name, 874 file->f_path.dentry->d_parent->d_name.name,
768 file->f_path.dentry->d_name.name, 875 file->f_path.dentry->d_name.name,
769 (unsigned long) count, (long long) pos); 876 count, (long long) pos);
770
771 if (nr_segs != 1)
772 goto out;
773 877
774 retval = -EFAULT;
775 if (!access_ok(VERIFY_WRITE, buf, count))
776 goto out;
777 retval = 0; 878 retval = 0;
778 if (!count) 879 if (!count)
779 goto out; 880 goto out;
@@ -782,7 +883,7 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, const struct iovec *iov,
782 if (retval) 883 if (retval)
783 goto out; 884 goto out;
784 885
785 retval = nfs_direct_read(iocb, (unsigned long) buf, count, pos); 886 retval = nfs_direct_read(iocb, iov, nr_segs, pos);
786 if (retval > 0) 887 if (retval > 0)
787 iocb->ki_pos = pos + retval; 888 iocb->ki_pos = pos + retval;
788 889
@@ -821,17 +922,15 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov,
821 ssize_t retval = -EINVAL; 922 ssize_t retval = -EINVAL;
822 struct file *file = iocb->ki_filp; 923 struct file *file = iocb->ki_filp;
823 struct address_space *mapping = file->f_mapping; 924 struct address_space *mapping = file->f_mapping;
824 /* XXX: temporary */ 925 size_t count;
825 const char __user *buf = iov[0].iov_base; 926
826 size_t count = iov[0].iov_len; 927 count = iov_length(iov, nr_segs);
928 nfs_add_stats(mapping->host, NFSIOS_DIRECTWRITTENBYTES, count);
827 929
828 dprintk("nfs: direct write(%s/%s, %lu@%Ld)\n", 930 dfprintk(VFS, "nfs: direct write(%s/%s, %zd@%Ld)\n",
829 file->f_path.dentry->d_parent->d_name.name, 931 file->f_path.dentry->d_parent->d_name.name,
830 file->f_path.dentry->d_name.name, 932 file->f_path.dentry->d_name.name,
831 (unsigned long) count, (long long) pos); 933 count, (long long) pos);
832
833 if (nr_segs != 1)
834 goto out;
835 934
836 retval = generic_write_checks(file, &pos, &count, 0); 935 retval = generic_write_checks(file, &pos, &count, 0);
837 if (retval) 936 if (retval)
@@ -844,15 +943,11 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov,
844 if (!count) 943 if (!count)
845 goto out; 944 goto out;
846 945
847 retval = -EFAULT;
848 if (!access_ok(VERIFY_READ, buf, count))
849 goto out;
850
851 retval = nfs_sync_mapping(mapping); 946 retval = nfs_sync_mapping(mapping);
852 if (retval) 947 if (retval)
853 goto out; 948 goto out;
854 949
855 retval = nfs_direct_write(iocb, (unsigned long) buf, count, pos); 950 retval = nfs_direct_write(iocb, iov, nr_segs, pos, count);
856 951
857 if (retval > 0) 952 if (retval > 0)
858 iocb->ki_pos = pos + retval; 953 iocb->ki_pos = pos + retval;