aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/pagelist.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/pagelist.c')
-rw-r--r--fs/nfs/pagelist.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 745a612dbe22..0be5050638f7 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -29,8 +29,6 @@
29static struct kmem_cache *nfs_page_cachep; 29static struct kmem_cache *nfs_page_cachep;
30static const struct rpc_call_ops nfs_pgio_common_ops; 30static const struct rpc_call_ops nfs_pgio_common_ops;
31 31
32static void nfs_free_request(struct nfs_page *);
33
34static bool nfs_pgarray_set(struct nfs_page_array *p, unsigned int pagecount) 32static bool nfs_pgarray_set(struct nfs_page_array *p, unsigned int pagecount)
35{ 33{
36 p->npages = pagecount; 34 p->npages = pagecount;
@@ -232,20 +230,28 @@ nfs_page_group_init(struct nfs_page *req, struct nfs_page *prev)
232 WARN_ON_ONCE(prev == req); 230 WARN_ON_ONCE(prev == req);
233 231
234 if (!prev) { 232 if (!prev) {
233 /* a head request */
235 req->wb_head = req; 234 req->wb_head = req;
236 req->wb_this_page = req; 235 req->wb_this_page = req;
237 } else { 236 } else {
237 /* a subrequest */
238 WARN_ON_ONCE(prev->wb_this_page != prev->wb_head); 238 WARN_ON_ONCE(prev->wb_this_page != prev->wb_head);
239 WARN_ON_ONCE(!test_bit(PG_HEADLOCK, &prev->wb_head->wb_flags)); 239 WARN_ON_ONCE(!test_bit(PG_HEADLOCK, &prev->wb_head->wb_flags));
240 req->wb_head = prev->wb_head; 240 req->wb_head = prev->wb_head;
241 req->wb_this_page = prev->wb_this_page; 241 req->wb_this_page = prev->wb_this_page;
242 prev->wb_this_page = req; 242 prev->wb_this_page = req;
243 243
244 /* All subrequests take a ref on the head request until
245 * nfs_page_group_destroy is called */
246 kref_get(&req->wb_head->wb_kref);
247
244 /* grab extra ref if head request has extra ref from 248 /* grab extra ref if head request has extra ref from
245 * the write/commit path to handle handoff between write 249 * the write/commit path to handle handoff between write
246 * and commit lists */ 250 * and commit lists */
247 if (test_bit(PG_INODE_REF, &prev->wb_head->wb_flags)) 251 if (test_bit(PG_INODE_REF, &prev->wb_head->wb_flags)) {
252 set_bit(PG_INODE_REF, &req->wb_flags);
248 kref_get(&req->wb_kref); 253 kref_get(&req->wb_kref);
254 }
249 } 255 }
250} 256}
251 257
@@ -262,6 +268,10 @@ nfs_page_group_destroy(struct kref *kref)
262 struct nfs_page *req = container_of(kref, struct nfs_page, wb_kref); 268 struct nfs_page *req = container_of(kref, struct nfs_page, wb_kref);
263 struct nfs_page *tmp, *next; 269 struct nfs_page *tmp, *next;
264 270
271 /* subrequests must release the ref on the head request */
272 if (req->wb_head != req)
273 nfs_release_request(req->wb_head);
274
265 if (!nfs_page_group_sync_on_bit(req, PG_TEARDOWN)) 275 if (!nfs_page_group_sync_on_bit(req, PG_TEARDOWN))
266 return; 276 return;
267 277
@@ -387,7 +397,7 @@ static void nfs_clear_request(struct nfs_page *req)
387 * 397 *
388 * Note: Should never be called with the spinlock held! 398 * Note: Should never be called with the spinlock held!
389 */ 399 */
390static void nfs_free_request(struct nfs_page *req) 400void nfs_free_request(struct nfs_page *req)
391{ 401{
392 WARN_ON_ONCE(req->wb_this_page != req); 402 WARN_ON_ONCE(req->wb_this_page != req);
393 403
@@ -917,7 +927,6 @@ static int __nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
917 nfs_pageio_doio(desc); 927 nfs_pageio_doio(desc);
918 if (desc->pg_error < 0) 928 if (desc->pg_error < 0)
919 return 0; 929 return 0;
920 desc->pg_moreio = 0;
921 if (desc->pg_recoalesce) 930 if (desc->pg_recoalesce)
922 return 0; 931 return 0;
923 /* retry add_request for this subreq */ 932 /* retry add_request for this subreq */
@@ -964,6 +973,7 @@ static int nfs_do_recoalesce(struct nfs_pageio_descriptor *desc)
964 desc->pg_count = 0; 973 desc->pg_count = 0;
965 desc->pg_base = 0; 974 desc->pg_base = 0;
966 desc->pg_recoalesce = 0; 975 desc->pg_recoalesce = 0;
976 desc->pg_moreio = 0;
967 977
968 while (!list_empty(&head)) { 978 while (!list_empty(&head)) {
969 struct nfs_page *req; 979 struct nfs_page *req;