aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorWeston Andros Adamson <dros@primarydata.com>2014-05-15 11:56:46 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2014-05-29 11:11:45 -0400
commit67d0338edd71db9a4f406d8778f7c525d31e9f7f (patch)
treee0fdbb1461b833681f641d3f8263d8499f9d644c /fs/nfs
parent2bfc6e566daa8386c9cffef2f7de17fc330d3835 (diff)
nfs: page group syncing in read path
Operations that modify state for a whole page must be syncronized across all requests within a page group. In the read path, this is calling unlock_page and SetPageUptodate. Both of these functions should not be called until all requests in a page group have reached the point where they would call them. This patch should have no effect yet since all page groups currently have one request, but will come into play when pg_test functions are modified to split pages into sub-page regions. Signed-off-by: Weston Andros Adamson <dros@primarydata.com> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/pagelist.c2
-rw-r--r--fs/nfs/read.c22
2 files changed, 19 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 }