mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-05 18:39:59 +00:00
NFSv4: Fix a sleep in atomic context in nfs4_callback_sequence()
commit8618289c46
upstream. We must drop the lock before we can sleep in referring_call_exists(). Reported-by: Jia-Ju Bai <baijiaju1990@gmail.com> Fixes:045d2a6d07
("NFSv4.1: Delay callback processing...") Cc: stable@vger.kernel.org # v4.9+ Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
c5759d5a7e
commit
d453f04e81
1 changed files with 10 additions and 4 deletions
|
@ -433,11 +433,14 @@ validate_seqid(const struct nfs4_slot_table *tbl, const struct nfs4_slot *slot,
|
|||
* a match. If the slot is in use and the sequence numbers match, the
|
||||
* client is still waiting for a response to the original request.
|
||||
*/
|
||||
static bool referring_call_exists(struct nfs_client *clp,
|
||||
static int referring_call_exists(struct nfs_client *clp,
|
||||
uint32_t nrclists,
|
||||
struct referring_call_list *rclists)
|
||||
struct referring_call_list *rclists,
|
||||
spinlock_t *lock)
|
||||
__releases(lock)
|
||||
__acquires(lock)
|
||||
{
|
||||
bool status = 0;
|
||||
int status = 0;
|
||||
int i, j;
|
||||
struct nfs4_session *session;
|
||||
struct nfs4_slot_table *tbl;
|
||||
|
@ -460,8 +463,10 @@ static bool referring_call_exists(struct nfs_client *clp,
|
|||
|
||||
for (j = 0; j < rclist->rcl_nrefcalls; j++) {
|
||||
ref = &rclist->rcl_refcalls[j];
|
||||
spin_unlock(lock);
|
||||
status = nfs4_slot_wait_on_seqid(tbl, ref->rc_slotid,
|
||||
ref->rc_sequenceid, HZ >> 1) < 0;
|
||||
spin_lock(lock);
|
||||
if (status)
|
||||
goto out;
|
||||
}
|
||||
|
@ -538,7 +543,8 @@ __be32 nfs4_callback_sequence(void *argp, void *resp,
|
|||
* related callback was received before the response to the original
|
||||
* call.
|
||||
*/
|
||||
if (referring_call_exists(clp, args->csa_nrclists, args->csa_rclists)) {
|
||||
if (referring_call_exists(clp, args->csa_nrclists, args->csa_rclists,
|
||||
&tbl->slot_tbl_lock) < 0) {
|
||||
status = htonl(NFS4ERR_DELAY);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue