Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 85710a83 authored by Weston Andros Adamson's avatar Weston Andros Adamson Committed by Trond Myklebust
Browse files

nfs: nfs_page should take a ref on the head req



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: default avatarWeston Andros Adamson <dros@primarydata.com>
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
parent 17089a29
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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 */
@@ -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;