Skip to content

Commit

Permalink
nfs: nfs_page should take a ref on the head req
Browse files Browse the repository at this point in the history
nfs_pages that aren't the the head of a group must take a reference on the
head as long as ->wb_head is set to it. This stops the head from hitting
a refcount of 0 while there is still an active nfs_page for the page group.

This avoids kref warnings in the writeback code when the page group head
is found and referenced.

Signed-off-by: Weston Andros Adamson <[email protected]>
Signed-off-by: Trond Myklebust <[email protected]>
  • Loading branch information
westonandrosadamson authored and trondmypd committed Jul 12, 2014
1 parent 17089a2 commit 85710a8
Showing 1 changed file with 10 additions and 0 deletions.
10 changes: 10 additions & 0 deletions fs/nfs/pagelist.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,15 +239,21 @@ nfs_page_group_init(struct nfs_page *req, struct nfs_page *prev)
WARN_ON_ONCE(prev == req);

if (!prev) {
/* a head request */
req->wb_head = req;
req->wb_this_page = req;
} else {
/* a subrequest */
WARN_ON_ONCE(prev->wb_this_page != prev->wb_head);
WARN_ON_ONCE(!test_bit(PG_HEADLOCK, &prev->wb_head->wb_flags));
req->wb_head = prev->wb_head;
req->wb_this_page = prev->wb_this_page;
prev->wb_this_page = req;

/* All subrequests take a ref on the head request until
* nfs_page_group_destroy is called */
kref_get(&req->wb_head->wb_kref);

/* grab extra ref if head request has extra ref from
* the write/commit path to handle handoff between write
* and commit lists */
Expand All @@ -271,6 +277,10 @@ nfs_page_group_destroy(struct kref *kref)
struct nfs_page *req = container_of(kref, struct nfs_page, wb_kref);
struct nfs_page *tmp, *next;

/* subrequests must release the ref on the head request */
if (req->wb_head != req)
nfs_release_request(req->wb_head);

if (!nfs_page_group_sync_on_bit(req, PG_TEARDOWN))
return;

Expand Down

0 comments on commit 85710a8

Please sign in to comment.