[PATCH v2 21/28] direct read

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Fred Isaman <iisaman@xxxxxxxxxx>
---
 fs/nfs/direct.c |   21 ++++++++++++++-------
 1 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index d713234..4ba9a2c 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -222,18 +222,17 @@ void nfs_direct_readpage_release(struct nfs_page *req)
 
 static void nfs_direct_read_completion(struct nfs_pgio_header *hdr)
 {
-	unsigned long pos = req_offset(hdr->req);
+	unsigned long bytes = 0;
 	struct nfs_direct_req *dreq = hdr->dreq;
 
 	if (test_bit(NFS_IOHDR_REDO, &hdr->flags))
 		goto out_put;
 
 	spin_lock(&dreq->lock);
-	if (test_bit(NFS_IOHDR_ERROR, &hdr->flags) &&
-	    (hdr->first_error == pos))
+	if (test_bit(NFS_IOHDR_ERROR, &hdr->flags) && (hdr->good_bytes == 0))
 		dreq->error = hdr->error;
 	else
-		dreq->count += (hdr->first_error - pos);
+		dreq->count += hdr->good_bytes;
 	spin_unlock(&dreq->lock);
 
 	if (!test_bit(NFS_IOHDR_ERROR, &hdr->flags)) {
@@ -241,6 +240,15 @@ static void nfs_direct_read_completion(struct nfs_pgio_header *hdr)
 			struct nfs_page *req = nfs_list_entry(hdr->pages.next);
 			struct page *page = req->wb_page;
 
+			if (test_bit(NFS_IOHDR_EOF, &hdr->flags)) {
+				if (bytes > hdr->good_bytes)
+					zero_user(page, 0, PAGE_SIZE);
+				else if (hdr->good_bytes - bytes < PAGE_SIZE)
+					zero_user_segment(page,
+						hdr->good_bytes & ~PAGE_MASK,
+						PAGE_SIZE);
+			}
+			bytes += req->wb_bytes;
 			nfs_list_remove_request(req);
 			nfs_direct_readpage_release(req);
 			if (!PageCompound(page))
@@ -248,17 +256,16 @@ static void nfs_direct_read_completion(struct nfs_pgio_header *hdr)
 			page_cache_release(page);
 		}
 	} else {
-		pos &= PAGE_MASK;
 		while (!list_empty(&hdr->pages)) {
 			struct nfs_page *req = nfs_list_entry(hdr->pages.next);
 
-			if (pos < (hdr->first_error & PAGE_MASK))
+			if (bytes < hdr->good_bytes)
 				if (!PageCompound(req->wb_page))
 					set_page_dirty(req->wb_page);
+			bytes += req->wb_bytes;
 			page_cache_release(req->wb_page);
 			nfs_list_remove_request(req);
 			nfs_direct_readpage_release(req);
-			pos += PAGE_SIZE;
 		}
 	}
 out_put:
-- 
1.7.2.1

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux