FAILED: patch "[PATCH] NFS: Fix I/O request leakages" failed to apply to 4.4-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From f57dcf4c72113c745d83f1c65f7291299f65c14f Mon Sep 17 00:00:00 2001
From: Trond Myklebust <[email protected]>
Date: Wed, 13 Feb 2019 09:21:38 -0500
Subject: [PATCH] NFS: Fix I/O request leakages
When we fail to add the request to the I/O queue, we currently leave it to the caller to free the failed request. However since some of the requests that fail are actually created by nfs_pageio_add_request() itself, and are not passed back the caller, this leads to a leakage issue, which can again cause page locks to leak.
This commit addresses the leakage by freeing the created requests on error, using desc->pg_completion_ops->error_cleanup()
fs/nfs/pagelist.c +21 -5
@@ -988,6 +988,17 @@ static void nfs_pageio_doio(struct nfs_pageio_descriptor *desc) } } +static void +nfs_pageio_cleanup_request (struct nfs_pageio_descriptor *desc, +struct nfs_page *req) +{ +LIST_HEAD (head); + +nfs_list_remove_request (req); +nfs_list_add_request (req, &head); + desc->pg_completion_ops->error_cleanup (&head); +} +/** * nfs_pageio_add_request - Attempt to coalesce a request into a page list. * @desc: destination io descriptor
@@ -1025,10 +1036,8 @@ static int __nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,nfs_page_group_unlock (req); desc->pg_moreio =1 ;nfs_pageio_doio (desc); -if (desc->pg_error <0 ) -return 0 ; -if (mirror->pg_recoalesce) -return 0 ; +if (desc->pg_error <0 || mirror->pg_recoalesce) + goto out_cleanup_subreq;/* retry add_request for this subreq */ nfs_page_group_lock (req);continue ;
@@ -1061,6 +1070,10 @@ static int __nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, desc->pg_error =PTR_ERR (subreq);nfs_page_group_unlock (req);return 0 ; +out_cleanup_subreq: +if (req != subreq) +nfs_pageio_cleanup_request (desc, subreq); +return 0 ; }static int nfs_do_recoalesce (struct nfs_pageio_descriptor *desc)
@@ -1168,11 +1181,14 @@ int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,if (nfs_pgio_has_mirroring (desc)) desc->pg_mirror_idx = midx;if (!nfs_pageio_add_request_mirror (desc, dupreq)) - goto out_failed; + goto out_cleanup_subreq; }return 1 ; +out_cleanup_subreq: +if (req != dupreq) +nfs_pageio_cleanup_request (desc, dupreq); out_failed:nfs_pageio_error_cleanup (desc);return 0 ;