Skip to content

Commit

Permalink
NFS: Fix a potential busy wait in nfs_page_group_lock
Browse files Browse the repository at this point in the history
We cannot allow nfs_page_group_lock to use TASK_KILLABLE here, since
the loop would cause a busy wait if somebody kills the task.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
  • Loading branch information
Trond Myklebust committed May 29, 2014
1 parent c110955 commit f868089
Showing 1 changed file with 9 additions and 10 deletions.
19 changes: 9 additions & 10 deletions fs/nfs/pagelist.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,12 @@ nfs_iocounter_wait(struct nfs_io_counter *c)
return __nfs_iocounter_wait(c);
}

static int nfs_wait_bit_uninterruptible(void *word)
{
io_schedule();
return 0;
}

/*
* nfs_page_group_lock - lock the head of the page group
* @req - request in group that is to be locked
Expand All @@ -148,13 +154,12 @@ void
nfs_page_group_lock(struct nfs_page *req)
{
struct nfs_page *head = req->wb_head;
int err = -EAGAIN;

WARN_ON_ONCE(head != head->wb_head);

while (err)
err = wait_on_bit_lock(&head->wb_flags, PG_HEADLOCK,
nfs_wait_bit_killable, TASK_KILLABLE);
wait_on_bit_lock(&head->wb_flags, PG_HEADLOCK,
nfs_wait_bit_uninterruptible,
TASK_UNINTERRUPTIBLE);
}

/*
Expand Down Expand Up @@ -410,12 +415,6 @@ void nfs_release_request(struct nfs_page *req)
kref_put(&req->wb_kref, nfs_page_group_destroy);
}

static int nfs_wait_bit_uninterruptible(void *word)
{
io_schedule();
return 0;
}

/**
* nfs_wait_on_request - Wait for a request to complete.
* @req: request to wait upon.
Expand Down

0 comments on commit f868089

Please sign in to comment.