]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.14.69/nfsv4-fix-a-sleep-in-atomic-context-in-nfs4_callback_sequence.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.14.69 / nfsv4-fix-a-sleep-in-atomic-context-in-nfs4_callback_sequence.patch
1 From 8618289c46556fd4dd259a1af02ccc448032f48d Mon Sep 17 00:00:00 2001
2 From: Trond Myklebust <trondmy@gmail.com>
3 Date: Tue, 14 Aug 2018 17:55:56 -0400
4 Subject: NFSv4: Fix a sleep in atomic context in nfs4_callback_sequence()
5
6 From: Trond Myklebust <trondmy@gmail.com>
7
8 commit 8618289c46556fd4dd259a1af02ccc448032f48d upstream.
9
10 We must drop the lock before we can sleep in referring_call_exists().
11
12 Reported-by: Jia-Ju Bai <baijiaju1990@gmail.com>
13 Fixes: 045d2a6d076a ("NFSv4.1: Delay callback processing...")
14 Cc: stable@vger.kernel.org # v4.9+
15 Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
16 Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
17 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
18
19 ---
20 fs/nfs/callback_proc.c | 14 ++++++++++----
21 1 file changed, 10 insertions(+), 4 deletions(-)
22
23 --- a/fs/nfs/callback_proc.c
24 +++ b/fs/nfs/callback_proc.c
25 @@ -433,11 +433,14 @@ validate_seqid(const struct nfs4_slot_ta
26 * a match. If the slot is in use and the sequence numbers match, the
27 * client is still waiting for a response to the original request.
28 */
29 -static bool referring_call_exists(struct nfs_client *clp,
30 +static int referring_call_exists(struct nfs_client *clp,
31 uint32_t nrclists,
32 - struct referring_call_list *rclists)
33 + struct referring_call_list *rclists,
34 + spinlock_t *lock)
35 + __releases(lock)
36 + __acquires(lock)
37 {
38 - bool status = 0;
39 + int status = 0;
40 int i, j;
41 struct nfs4_session *session;
42 struct nfs4_slot_table *tbl;
43 @@ -460,8 +463,10 @@ static bool referring_call_exists(struct
44
45 for (j = 0; j < rclist->rcl_nrefcalls; j++) {
46 ref = &rclist->rcl_refcalls[j];
47 + spin_unlock(lock);
48 status = nfs4_slot_wait_on_seqid(tbl, ref->rc_slotid,
49 ref->rc_sequenceid, HZ >> 1) < 0;
50 + spin_lock(lock);
51 if (status)
52 goto out;
53 }
54 @@ -538,7 +543,8 @@ __be32 nfs4_callback_sequence(void *argp
55 * related callback was received before the response to the original
56 * call.
57 */
58 - if (referring_call_exists(clp, args->csa_nrclists, args->csa_rclists)) {
59 + if (referring_call_exists(clp, args->csa_nrclists, args->csa_rclists,
60 + &tbl->slot_tbl_lock) < 0) {
61 status = htonl(NFS4ERR_DELAY);
62 goto out_unlock;
63 }