NFS: Ensure we always dereference the page head last
This fixes a race with nfs_page_group_sync_on_bit() whereby the call to wake_up_bit() in nfs_page_group_unlock() could occur after the page header had been freed. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
This commit is contained in:
parent
1403390d83
commit
08fead2ae5
|
@ -306,14 +306,11 @@ static void
|
|||
nfs_page_group_destroy(struct kref *kref)
|
||||
{
|
||||
struct nfs_page *req = container_of(kref, struct nfs_page, wb_kref);
|
||||
struct nfs_page *head = req->wb_head;
|
||||
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;
|
||||
goto out;
|
||||
|
||||
tmp = req;
|
||||
do {
|
||||
|
@ -324,6 +321,10 @@ nfs_page_group_destroy(struct kref *kref)
|
|||
nfs_free_request(tmp);
|
||||
tmp = next;
|
||||
} while (tmp != req);
|
||||
out:
|
||||
/* subrequests must release the ref on the head request */
|
||||
if (head != req)
|
||||
nfs_release_request(head);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue