aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/pagelist.c2
-rw-r--r--fs/nfs/read.c22
-rw-r--r--include/linux/nfs_page.h2
3 files changed, 21 insertions, 5 deletions
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 015fb7b48dfe..18ee4e99347e 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -395,6 +395,8 @@ static void nfs_free_request(struct nfs_page *req)
395 395
396 /* extra debug: make sure no sync bits are still set */ 396 /* extra debug: make sure no sync bits are still set */
397 WARN_ON_ONCE(test_bit(PG_TEARDOWN, &req->wb_flags)); 397 WARN_ON_ONCE(test_bit(PG_TEARDOWN, &req->wb_flags));
398 WARN_ON_ONCE(test_bit(PG_UNLOCKPAGE, &req->wb_flags));
399 WARN_ON_ONCE(test_bit(PG_UPTODATE, &req->wb_flags));
398 400
399 /* Release struct file and open context */ 401 /* Release struct file and open context */
400 nfs_clear_request(req); 402 nfs_clear_request(req);
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 902ba2c63d05..53d5b83611ce 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -105,10 +105,16 @@ static void nfs_readpage_release(struct nfs_page *req)
105{ 105{
106 struct inode *d_inode = req->wb_context->dentry->d_inode; 106 struct inode *d_inode = req->wb_context->dentry->d_inode;
107 107
108 if (PageUptodate(req->wb_page)) 108 dprintk("NFS: read done (%s/%llu %d@%lld)\n", d_inode->i_sb->s_id,
109 nfs_readpage_to_fscache(d_inode, req->wb_page, 0); 109 (unsigned long long)NFS_FILEID(d_inode), req->wb_bytes,
110 (long long)req_offset(req));
110 111
111 unlock_page(req->wb_page); 112 if (nfs_page_group_sync_on_bit(req, PG_UNLOCKPAGE)) {
113 if (PageUptodate(req->wb_page))
114 nfs_readpage_to_fscache(d_inode, req->wb_page, 0);
115
116 unlock_page(req->wb_page);
117 }
112 118
113 dprintk("NFS: read done (%s/%Lu %d@%Ld)\n", 119 dprintk("NFS: read done (%s/%Lu %d@%Ld)\n",
114 req->wb_context->dentry->d_inode->i_sb->s_id, 120 req->wb_context->dentry->d_inode->i_sb->s_id,
@@ -118,6 +124,12 @@ static void nfs_readpage_release(struct nfs_page *req)
118 nfs_release_request(req); 124 nfs_release_request(req);
119} 125}
120 126
127static void nfs_page_group_set_uptodate(struct nfs_page *req)
128{
129 if (nfs_page_group_sync_on_bit(req, PG_UPTODATE))
130 SetPageUptodate(req->wb_page);
131}
132
121/* Note io was page aligned */ 133/* Note io was page aligned */
122static void nfs_read_completion(struct nfs_pgio_header *hdr) 134static void nfs_read_completion(struct nfs_pgio_header *hdr)
123{ 135{
@@ -140,9 +152,9 @@ static void nfs_read_completion(struct nfs_pgio_header *hdr)
140 bytes += req->wb_bytes; 152 bytes += req->wb_bytes;
141 if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) { 153 if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) {
142 if (bytes <= hdr->good_bytes) 154 if (bytes <= hdr->good_bytes)
143 SetPageUptodate(page); 155 nfs_page_group_set_uptodate(req);
144 } else 156 } else
145 SetPageUptodate(page); 157 nfs_page_group_set_uptodate(req);
146 nfs_list_remove_request(req); 158 nfs_list_remove_request(req);
147 nfs_readpage_release(req); 159 nfs_readpage_release(req);
148 } 160 }
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
index 986c0c279d0e..6385175a127b 100644
--- a/include/linux/nfs_page.h
+++ b/include/linux/nfs_page.h
@@ -29,6 +29,8 @@ enum {
29 PG_INODE_REF, /* extra ref held by inode (head req only) */ 29 PG_INODE_REF, /* extra ref held by inode (head req only) */
30 PG_HEADLOCK, /* page group lock of wb_head */ 30 PG_HEADLOCK, /* page group lock of wb_head */
31 PG_TEARDOWN, /* page group sync for destroy */ 31 PG_TEARDOWN, /* page group sync for destroy */
32 PG_UNLOCKPAGE, /* page group sync bit in read path */
33 PG_UPTODATE, /* page group sync bit in read path */
32}; 34};
33 35
34struct nfs_inode; 36struct nfs_inode;