NFS: Don't fail an O_DIRECT read/write if get_user_pages() returns pages
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Tue, 22 May 2007 14:22:20 +0000 (10:22 -0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Wed, 11 Jul 2007 03:40:23 +0000 (23:40 -0400)
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>
fs/nfs/direct.c

index 4c97e55e86ee87747cebbea24a458cfc1803f369..f1b153ad645b6788d691b567b6cded4a9f2fbc67 100644 (file)
@@ -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);