]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.19.31/nfs-fix-i-o-request-leakages.patch
Linux 4.19.31
[thirdparty/kernel/stable-queue.git] / releases / 4.19.31 / nfs-fix-i-o-request-leakages.patch
1 From f57dcf4c72113c745d83f1c65f7291299f65c14f Mon Sep 17 00:00:00 2001
2 From: Trond Myklebust <trond.myklebust@hammerspace.com>
3 Date: Wed, 13 Feb 2019 09:21:38 -0500
4 Subject: NFS: Fix I/O request leakages
5
6 From: Trond Myklebust <trond.myklebust@hammerspace.com>
7
8 commit f57dcf4c72113c745d83f1c65f7291299f65c14f upstream.
9
10 When we fail to add the request to the I/O queue, we currently leave it
11 to the caller to free the failed request. However since some of the
12 requests that fail are actually created by nfs_pageio_add_request()
13 itself, and are not passed back the caller, this leads to a leakage
14 issue, which can again cause page locks to leak.
15
16 This commit addresses the leakage by freeing the created requests on
17 error, using desc->pg_completion_ops->error_cleanup()
18
19 Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
20 Fixes: a7d42ddb30997 ("nfs: add mirroring support to pgio layer")
21 Cc: stable@vger.kernel.org # v4.0: c18b96a1b862: nfs: clean up rest of reqs
22 Cc: stable@vger.kernel.org # v4.0: d600ad1f2bdb: NFS41: pop some layoutget
23 Cc: stable@vger.kernel.org # v4.0+
24 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
25
26 ---
27 fs/nfs/pagelist.c | 26 +++++++++++++++++++++-----
28 1 file changed, 21 insertions(+), 5 deletions(-)
29
30 --- a/fs/nfs/pagelist.c
31 +++ b/fs/nfs/pagelist.c
32 @@ -989,6 +989,17 @@ static void nfs_pageio_doio(struct nfs_p
33 }
34 }
35
36 +static void
37 +nfs_pageio_cleanup_request(struct nfs_pageio_descriptor *desc,
38 + struct nfs_page *req)
39 +{
40 + LIST_HEAD(head);
41 +
42 + nfs_list_remove_request(req);
43 + nfs_list_add_request(req, &head);
44 + desc->pg_completion_ops->error_cleanup(&head);
45 +}
46 +
47 /**
48 * nfs_pageio_add_request - Attempt to coalesce a request into a page list.
49 * @desc: destination io descriptor
50 @@ -1026,10 +1037,8 @@ static int __nfs_pageio_add_request(stru
51 nfs_page_group_unlock(req);
52 desc->pg_moreio = 1;
53 nfs_pageio_doio(desc);
54 - if (desc->pg_error < 0)
55 - return 0;
56 - if (mirror->pg_recoalesce)
57 - return 0;
58 + if (desc->pg_error < 0 || mirror->pg_recoalesce)
59 + goto out_cleanup_subreq;
60 /* retry add_request for this subreq */
61 nfs_page_group_lock(req);
62 continue;
63 @@ -1062,6 +1071,10 @@ err_ptr:
64 desc->pg_error = PTR_ERR(subreq);
65 nfs_page_group_unlock(req);
66 return 0;
67 +out_cleanup_subreq:
68 + if (req != subreq)
69 + nfs_pageio_cleanup_request(desc, subreq);
70 + return 0;
71 }
72
73 static int nfs_do_recoalesce(struct nfs_pageio_descriptor *desc)
74 @@ -1169,11 +1182,14 @@ int nfs_pageio_add_request(struct nfs_pa
75 if (nfs_pgio_has_mirroring(desc))
76 desc->pg_mirror_idx = midx;
77 if (!nfs_pageio_add_request_mirror(desc, dupreq))
78 - goto out_failed;
79 + goto out_cleanup_subreq;
80 }
81
82 return 1;
83
84 +out_cleanup_subreq:
85 + if (req != dupreq)
86 + nfs_pageio_cleanup_request(desc, dupreq);
87 out_failed:
88 /* remember fatal errors */
89 if (nfs_error_is_fatal(desc->pg_error))