diff options
| -rw-r--r-- | fs/nfs/direct.c | 67 |
1 files changed, 23 insertions, 44 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index e30d9285a566..88d5d1c7f987 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
| @@ -272,8 +272,6 @@ static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned lo | |||
| 272 | int result; | 272 | int result; |
| 273 | ssize_t started = 0; | 273 | ssize_t started = 0; |
| 274 | 274 | ||
| 275 | get_dreq(dreq); | ||
| 276 | |||
| 277 | do { | 275 | do { |
| 278 | struct nfs_read_data *data; | 276 | struct nfs_read_data *data; |
| 279 | size_t bytes; | 277 | size_t bytes; |
| @@ -347,11 +345,8 @@ static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned lo | |||
| 347 | count -= bytes; | 345 | count -= bytes; |
| 348 | } while (count != 0); | 346 | } while (count != 0); |
| 349 | 347 | ||
| 350 | if (put_dreq(dreq)) | ||
| 351 | nfs_direct_complete(dreq); | ||
| 352 | |||
| 353 | if (started) | 348 | if (started) |
| 354 | return 0; | 349 | return started; |
| 355 | return result < 0 ? (ssize_t) result : -EFAULT; | 350 | return result < 0 ? (ssize_t) result : -EFAULT; |
| 356 | } | 351 | } |
| 357 | 352 | ||
| @@ -390,7 +385,8 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq, | |||
| 390 | return -EIO; | 385 | return -EIO; |
| 391 | } | 386 | } |
| 392 | 387 | ||
| 393 | static ssize_t nfs_direct_read(struct kiocb *iocb, unsigned long user_addr, size_t count, loff_t pos) | 388 | static ssize_t nfs_direct_read(struct kiocb *iocb, const struct iovec *iov, |
| 389 | unsigned long nr_segs, loff_t pos) | ||
| 394 | { | 390 | { |
| 395 | ssize_t result = 0; | 391 | ssize_t result = 0; |
| 396 | sigset_t oldset; | 392 | sigset_t oldset; |
| @@ -407,9 +403,8 @@ static ssize_t nfs_direct_read(struct kiocb *iocb, unsigned long user_addr, size | |||
| 407 | if (!is_sync_kiocb(iocb)) | 403 | if (!is_sync_kiocb(iocb)) |
| 408 | dreq->iocb = iocb; | 404 | dreq->iocb = iocb; |
| 409 | 405 | ||
| 410 | nfs_add_stats(inode, NFSIOS_DIRECTREADBYTES, count); | ||
| 411 | rpc_clnt_sigmask(clnt, &oldset); | 406 | rpc_clnt_sigmask(clnt, &oldset); |
| 412 | result = nfs_direct_read_schedule(dreq, user_addr, count, pos); | 407 | result = nfs_direct_read_schedule_iovec(dreq, iov, nr_segs, pos); |
| 413 | if (!result) | 408 | if (!result) |
| 414 | result = nfs_direct_wait(dreq); | 409 | result = nfs_direct_wait(dreq); |
| 415 | rpc_clnt_sigunmask(clnt, &oldset); | 410 | rpc_clnt_sigunmask(clnt, &oldset); |
| @@ -645,8 +640,6 @@ static ssize_t nfs_direct_write_schedule(struct nfs_direct_req *dreq, unsigned l | |||
| 645 | int result; | 640 | int result; |
| 646 | ssize_t started = 0; | 641 | ssize_t started = 0; |
| 647 | 642 | ||
| 648 | get_dreq(dreq); | ||
| 649 | |||
| 650 | do { | 643 | do { |
| 651 | struct nfs_write_data *data; | 644 | struct nfs_write_data *data; |
| 652 | size_t bytes; | 645 | size_t bytes; |
| @@ -724,11 +717,8 @@ static ssize_t nfs_direct_write_schedule(struct nfs_direct_req *dreq, unsigned l | |||
| 724 | count -= bytes; | 717 | count -= bytes; |
| 725 | } while (count != 0); | 718 | } while (count != 0); |
| 726 | 719 | ||
| 727 | if (put_dreq(dreq)) | ||
| 728 | nfs_direct_write_complete(dreq, inode); | ||
| 729 | |||
| 730 | if (started) | 720 | if (started) |
| 731 | return 0; | 721 | return started; |
| 732 | return result < 0 ? (ssize_t) result : -EFAULT; | 722 | return result < 0 ? (ssize_t) result : -EFAULT; |
| 733 | } | 723 | } |
| 734 | 724 | ||
| @@ -768,7 +758,9 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq, | |||
| 768 | return -EIO; | 758 | return -EIO; |
| 769 | } | 759 | } |
| 770 | 760 | ||
| 771 | static ssize_t nfs_direct_write(struct kiocb *iocb, unsigned long user_addr, size_t count, loff_t pos) | 761 | static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov, |
| 762 | unsigned long nr_segs, loff_t pos, | ||
| 763 | size_t count) | ||
| 772 | { | 764 | { |
| 773 | ssize_t result = 0; | 765 | ssize_t result = 0; |
| 774 | sigset_t oldset; | 766 | sigset_t oldset; |
| @@ -791,10 +783,8 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, unsigned long user_addr, siz | |||
| 791 | if (!is_sync_kiocb(iocb)) | 783 | if (!is_sync_kiocb(iocb)) |
| 792 | dreq->iocb = iocb; | 784 | dreq->iocb = iocb; |
| 793 | 785 | ||
| 794 | nfs_add_stats(inode, NFSIOS_DIRECTWRITTENBYTES, count); | ||
| 795 | |||
| 796 | rpc_clnt_sigmask(clnt, &oldset); | 786 | rpc_clnt_sigmask(clnt, &oldset); |
| 797 | result = nfs_direct_write_schedule(dreq, user_addr, count, pos, sync); | 787 | result = nfs_direct_write_schedule_iovec(dreq, iov, nr_segs, pos, sync); |
| 798 | if (!result) | 788 | if (!result) |
| 799 | result = nfs_direct_wait(dreq); | 789 | result = nfs_direct_wait(dreq); |
| 800 | rpc_clnt_sigunmask(clnt, &oldset); | 790 | rpc_clnt_sigunmask(clnt, &oldset); |
| @@ -830,21 +820,16 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, const struct iovec *iov, | |||
| 830 | ssize_t retval = -EINVAL; | 820 | ssize_t retval = -EINVAL; |
| 831 | struct file *file = iocb->ki_filp; | 821 | struct file *file = iocb->ki_filp; |
| 832 | struct address_space *mapping = file->f_mapping; | 822 | struct address_space *mapping = file->f_mapping; |
| 833 | /* XXX: temporary */ | 823 | size_t count; |
| 834 | const char __user *buf = iov[0].iov_base; | 824 | |
| 835 | size_t count = iov[0].iov_len; | 825 | count = iov_length(iov, nr_segs); |
| 826 | nfs_add_stats(mapping->host, NFSIOS_DIRECTREADBYTES, count); | ||
| 836 | 827 | ||
| 837 | dprintk("nfs: direct read(%s/%s, %lu@%Ld)\n", | 828 | dprintk("nfs: direct read(%s/%s, %zd@%Ld)\n", |
| 838 | file->f_path.dentry->d_parent->d_name.name, | 829 | file->f_path.dentry->d_parent->d_name.name, |
| 839 | file->f_path.dentry->d_name.name, | 830 | file->f_path.dentry->d_name.name, |
| 840 | (unsigned long) count, (long long) pos); | 831 | count, (long long) pos); |
| 841 | 832 | ||
| 842 | if (nr_segs != 1) | ||
| 843 | goto out; | ||
| 844 | |||
| 845 | retval = -EFAULT; | ||
| 846 | if (!access_ok(VERIFY_WRITE, buf, count)) | ||
| 847 | goto out; | ||
| 848 | retval = 0; | 833 | retval = 0; |
| 849 | if (!count) | 834 | if (!count) |
| 850 | goto out; | 835 | goto out; |
| @@ -853,7 +838,7 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, const struct iovec *iov, | |||
| 853 | if (retval) | 838 | if (retval) |
| 854 | goto out; | 839 | goto out; |
| 855 | 840 | ||
| 856 | retval = nfs_direct_read(iocb, (unsigned long) buf, count, pos); | 841 | retval = nfs_direct_read(iocb, iov, nr_segs, pos); |
| 857 | if (retval > 0) | 842 | if (retval > 0) |
| 858 | iocb->ki_pos = pos + retval; | 843 | iocb->ki_pos = pos + retval; |
| 859 | 844 | ||
| @@ -892,17 +877,15 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 892 | ssize_t retval = -EINVAL; | 877 | ssize_t retval = -EINVAL; |
| 893 | struct file *file = iocb->ki_filp; | 878 | struct file *file = iocb->ki_filp; |
| 894 | struct address_space *mapping = file->f_mapping; | 879 | struct address_space *mapping = file->f_mapping; |
| 895 | /* XXX: temporary */ | 880 | size_t count; |
| 896 | const char __user *buf = iov[0].iov_base; | ||
| 897 | size_t count = iov[0].iov_len; | ||
| 898 | 881 | ||
| 899 | dprintk("nfs: direct write(%s/%s, %lu@%Ld)\n", | 882 | count = iov_length(iov, nr_segs); |
| 883 | nfs_add_stats(mapping->host, NFSIOS_DIRECTWRITTENBYTES, count); | ||
| 884 | |||
| 885 | dfprintk(VFS, "nfs: direct write(%s/%s, %zd@%Ld)\n", | ||
| 900 | file->f_path.dentry->d_parent->d_name.name, | 886 | file->f_path.dentry->d_parent->d_name.name, |
| 901 | file->f_path.dentry->d_name.name, | 887 | file->f_path.dentry->d_name.name, |
| 902 | (unsigned long) count, (long long) pos); | 888 | count, (long long) pos); |
| 903 | |||
| 904 | if (nr_segs != 1) | ||
| 905 | goto out; | ||
| 906 | 889 | ||
| 907 | retval = generic_write_checks(file, &pos, &count, 0); | 890 | retval = generic_write_checks(file, &pos, &count, 0); |
| 908 | if (retval) | 891 | if (retval) |
| @@ -915,15 +898,11 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 915 | if (!count) | 898 | if (!count) |
| 916 | goto out; | 899 | goto out; |
| 917 | 900 | ||
| 918 | retval = -EFAULT; | ||
| 919 | if (!access_ok(VERIFY_READ, buf, count)) | ||
| 920 | goto out; | ||
| 921 | |||
| 922 | retval = nfs_sync_mapping(mapping); | 901 | retval = nfs_sync_mapping(mapping); |
| 923 | if (retval) | 902 | if (retval) |
| 924 | goto out; | 903 | goto out; |
| 925 | 904 | ||
| 926 | retval = nfs_direct_write(iocb, (unsigned long) buf, count, pos); | 905 | retval = nfs_direct_write(iocb, iov, nr_segs, pos, count); |
| 927 | 906 | ||
| 928 | if (retval > 0) | 907 | if (retval > 0) |
| 929 | iocb->ki_pos = pos + retval; | 908 | iocb->ki_pos = pos + retval; |
