summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2007-05-22 10:22:20 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2007-07-10 23:40:23 -0400
commitd9df8d6b38228afab519094048aa2c082b0b2cf4 (patch)
tree7bbe92c2ac8e3eab2179cd194dccc8f30bf63df5
parent070ea60214c1894c9eec86ca9aa5dff57a5ab525 (diff)
NFS: Don't fail an O_DIRECT read/write if get_user_pages() returns pages
There is no need to fail the entire O_DIRECT read/write just because get_user_pages() returned fewer pages than we requested. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/direct.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 4c97e55e86e..f1b153ad645 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -295,9 +295,14 @@ static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned lo
break;
}
if ((unsigned)result < data->npages) {
- nfs_direct_release_pages(data->pagevec, result);
- nfs_readdata_release(data);
- break;
+ bytes = result * PAGE_SIZE;
+ if (bytes <= pgbase) {
+ nfs_direct_release_pages(data->pagevec, result);
+ nfs_readdata_release(data);
+ break;
+ }
+ bytes -= pgbase;
+ data->npages = result;
}
get_dreq(dreq);
@@ -630,9 +635,14 @@ static ssize_t nfs_direct_write_schedule(struct nfs_direct_req *dreq, unsigned l
break;
}
if ((unsigned)result < data->npages) {
- nfs_direct_release_pages(data->pagevec, result);
- nfs_writedata_release(data);
- break;
+ bytes = result * PAGE_SIZE;
+ if (bytes <= pgbase) {
+ nfs_direct_release_pages(data->pagevec, result);
+ nfs_writedata_release(data);
+ break;
+ }
+ bytes -= pgbase;
+ data->npages = result;
}
get_dreq(dreq);