diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-13 19:46:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-13 19:46:18 -0400 |
commit | 16cefa8c3863721fd40445a1b34dea18cd16ccfe (patch) | |
tree | c8e58ca06e2edfd667d3e6062a642b80cc58e5e7 /fs/nfs/direct.c | |
parent | 4fbef206daead133085fe33905f5e842d38fb8da (diff) | |
parent | d8558f99fbc5ef5d4ae76b893784005056450f82 (diff) |
Merge git://git.linux-nfs.org/pub/linux/nfs-2.6
* git://git.linux-nfs.org/pub/linux/nfs-2.6: (122 commits)
sunrpc: drop BKL around wrap and unwrap
NFSv4: Make sure unlock is really an unlock when cancelling a lock
NLM: fix source address of callback to client
SUNRPC client: add interface for binding to a local address
SUNRPC server: record the destination address of a request
SUNRPC: cleanup transport creation argument passing
NFSv4: Make the NFS state model work with the nosharedcache mount option
NFS: Error when mounting the same filesystem with different options
NFS: Add the mount option "nosharecache"
NFS: Add support for mounting NFSv4 file systems with string options
NFS: Add final pieces to support in-kernel mount option parsing
NFS: Introduce generic mount client API
NFS: Add enums and match tables for mount option parsing
NFS: Improve debugging output in NFS in-kernel mount client
NFS: Clean up in-kernel NFS mount
NFS: Remake nfsroot_mount as a permanent part of NFS client
SUNRPC: Add a convenient default for the hostname when calling rpc_create()
SUNRPC: Rename rpcb_getport to be consistent with new rpcb_getport_sync name
SUNRPC: Rename rpcb_getport_external routine
SUNRPC: Allow rpcbind requests to be interrupted by a signal.
...
Diffstat (limited to 'fs/nfs/direct.c')
-rw-r--r-- | fs/nfs/direct.c | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 00eee87510fe..a5c82b6f3b45 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
@@ -266,7 +266,7 @@ static const struct rpc_call_ops nfs_read_direct_ops = { | |||
266 | static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned long user_addr, size_t count, loff_t pos) | 266 | static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned long user_addr, size_t count, loff_t pos) |
267 | { | 267 | { |
268 | struct nfs_open_context *ctx = dreq->ctx; | 268 | struct nfs_open_context *ctx = dreq->ctx; |
269 | struct inode *inode = ctx->dentry->d_inode; | 269 | struct inode *inode = ctx->path.dentry->d_inode; |
270 | size_t rsize = NFS_SERVER(inode)->rsize; | 270 | size_t rsize = NFS_SERVER(inode)->rsize; |
271 | unsigned int pgbase; | 271 | unsigned int pgbase; |
272 | int result; | 272 | int result; |
@@ -295,9 +295,14 @@ static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned lo | |||
295 | break; | 295 | break; |
296 | } | 296 | } |
297 | if ((unsigned)result < data->npages) { | 297 | if ((unsigned)result < data->npages) { |
298 | nfs_direct_release_pages(data->pagevec, result); | 298 | bytes = result * PAGE_SIZE; |
299 | nfs_readdata_release(data); | 299 | if (bytes <= pgbase) { |
300 | break; | 300 | nfs_direct_release_pages(data->pagevec, result); |
301 | nfs_readdata_release(data); | ||
302 | break; | ||
303 | } | ||
304 | bytes -= pgbase; | ||
305 | data->npages = result; | ||
301 | } | 306 | } |
302 | 307 | ||
303 | get_dreq(dreq); | 308 | get_dreq(dreq); |
@@ -601,7 +606,7 @@ static const struct rpc_call_ops nfs_write_direct_ops = { | |||
601 | static ssize_t nfs_direct_write_schedule(struct nfs_direct_req *dreq, unsigned long user_addr, size_t count, loff_t pos, int sync) | 606 | static ssize_t nfs_direct_write_schedule(struct nfs_direct_req *dreq, unsigned long user_addr, size_t count, loff_t pos, int sync) |
602 | { | 607 | { |
603 | struct nfs_open_context *ctx = dreq->ctx; | 608 | struct nfs_open_context *ctx = dreq->ctx; |
604 | struct inode *inode = ctx->dentry->d_inode; | 609 | struct inode *inode = ctx->path.dentry->d_inode; |
605 | size_t wsize = NFS_SERVER(inode)->wsize; | 610 | size_t wsize = NFS_SERVER(inode)->wsize; |
606 | unsigned int pgbase; | 611 | unsigned int pgbase; |
607 | int result; | 612 | int result; |
@@ -630,9 +635,14 @@ static ssize_t nfs_direct_write_schedule(struct nfs_direct_req *dreq, unsigned l | |||
630 | break; | 635 | break; |
631 | } | 636 | } |
632 | if ((unsigned)result < data->npages) { | 637 | if ((unsigned)result < data->npages) { |
633 | nfs_direct_release_pages(data->pagevec, result); | 638 | bytes = result * PAGE_SIZE; |
634 | nfs_writedata_release(data); | 639 | if (bytes <= pgbase) { |
635 | break; | 640 | nfs_direct_release_pages(data->pagevec, result); |
641 | nfs_writedata_release(data); | ||
642 | break; | ||
643 | } | ||
644 | bytes -= pgbase; | ||
645 | data->npages = result; | ||
636 | } | 646 | } |
637 | 647 | ||
638 | get_dreq(dreq); | 648 | get_dreq(dreq); |
@@ -763,10 +773,8 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, const struct iovec *iov, | |||
763 | (unsigned long) count, (long long) pos); | 773 | (unsigned long) count, (long long) pos); |
764 | 774 | ||
765 | if (nr_segs != 1) | 775 | if (nr_segs != 1) |
766 | return -EINVAL; | ||
767 | |||
768 | if (count < 0) | ||
769 | goto out; | 776 | goto out; |
777 | |||
770 | retval = -EFAULT; | 778 | retval = -EFAULT; |
771 | if (!access_ok(VERIFY_WRITE, buf, count)) | 779 | if (!access_ok(VERIFY_WRITE, buf, count)) |
772 | goto out; | 780 | goto out; |
@@ -814,7 +822,7 @@ out: | |||
814 | ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov, | 822 | ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov, |
815 | unsigned long nr_segs, loff_t pos) | 823 | unsigned long nr_segs, loff_t pos) |
816 | { | 824 | { |
817 | ssize_t retval; | 825 | ssize_t retval = -EINVAL; |
818 | struct file *file = iocb->ki_filp; | 826 | struct file *file = iocb->ki_filp; |
819 | struct address_space *mapping = file->f_mapping; | 827 | struct address_space *mapping = file->f_mapping; |
820 | /* XXX: temporary */ | 828 | /* XXX: temporary */ |
@@ -827,7 +835,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov, | |||
827 | (unsigned long) count, (long long) pos); | 835 | (unsigned long) count, (long long) pos); |
828 | 836 | ||
829 | if (nr_segs != 1) | 837 | if (nr_segs != 1) |
830 | return -EINVAL; | 838 | goto out; |
831 | 839 | ||
832 | retval = generic_write_checks(file, &pos, &count, 0); | 840 | retval = generic_write_checks(file, &pos, &count, 0); |
833 | if (retval) | 841 | if (retval) |