]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.4.22/pnfs-ensure-layoutget-and-layoutreturn-are-properly-serialised.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.4.22 / pnfs-ensure-layoutget-and-layoutreturn-are-properly-serialised.patch
1 From bf0291dd2267a2b9a4cd74d65249553d11bb45d6 Mon Sep 17 00:00:00 2001
2 From: Trond Myklebust <trond.myklebust@primarydata.com>
3 Date: Sat, 3 Sep 2016 10:39:51 -0400
4 Subject: pNFS: Ensure LAYOUTGET and LAYOUTRETURN are properly serialised
5
6 From: Trond Myklebust <trond.myklebust@primarydata.com>
7
8 commit bf0291dd2267a2b9a4cd74d65249553d11bb45d6 upstream.
9
10 According to RFC5661, the client is responsible for serialising
11 LAYOUTGET and LAYOUTRETURN to avoid ambiguity. Consider the case
12 where we send both in parallel.
13
14 Client Server
15 ====== ======
16 LAYOUTGET(seqid=X)
17 LAYOUTRETURN(seqid=X)
18 LAYOUTGET return seqid=X+1
19 LAYOUTRETURN return seqid=X+2
20 Process LAYOUTRETURN
21 Forget layout stateid
22 Process LAYOUTGET
23 Set seqid=X+1
24
25 The client processes the layoutget/layoutreturn in the wrong order,
26 and since the result of the layoutreturn was to clear the only
27 existing layout segment, the client forgets the layout stateid.
28
29 When the LAYOUTGET comes in, it is treated as having a completely
30 new stateid, and so the client sets the wrong sequence id...
31
32 Fix is to check if there are outstanding LAYOUTGET requests
33 before we send the LAYOUTRETURN (note that LAYOUGET will already
34 wait if it sees an outstanding LAYOUTRETURN).
35
36 Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
37 Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
38 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
39
40 ---
41 fs/nfs/pnfs.c | 3 +++
42 1 file changed, 3 insertions(+)
43
44 --- a/fs/nfs/pnfs.c
45 +++ b/fs/nfs/pnfs.c
46 @@ -365,6 +365,9 @@ pnfs_layout_need_return(struct pnfs_layo
47 static bool
48 pnfs_prepare_layoutreturn(struct pnfs_layout_hdr *lo)
49 {
50 + /* Serialise LAYOUTGET/LAYOUTRETURN */
51 + if (atomic_read(&lo->plh_outstanding) != 0)
52 + return false;
53 if (test_and_set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags))
54 return false;
55 lo->plh_return_iomode = 0;