All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, JianhongYin <yin-jianhong@163.com>,
	Trond Myklebust <trond.myklebust@primarydata.com>
Subject: [PATCH 4.13 27/27] NFSv4: Fix up mirror allocation
Date: Tue, 12 Sep 2017 10:00:07 -0700	[thread overview]
Message-ID: <20170912165310.765255596@linuxfoundation.org> (raw)
In-Reply-To: <20170912165308.904472972@linuxfoundation.org>

4.13-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Trond Myklebust <trond.myklebust@primarydata.com>

commit 14abcb0bf59a30cf65a74f6c6f53974cd7224bc6 upstream.

There are a number of callers of nfs_pageio_complete() that want to
continue using the nfs_pageio_descriptor without needing to call
nfs_pageio_init() again. Examples include nfs_pageio_resend() and
nfs_pageio_cond_complete().

The problem is that nfs_pageio_complete() also calls
nfs_pageio_cleanup_mirroring(), which frees up the array of mirrors.
This can lead to writeback errors, in the next call to
nfs_pageio_setup_mirroring().

Fix by simply moving the allocation of the mirrors to
nfs_pageio_setup_mirroring().

Link: https://bugzilla.kernel.org/show_bug.cgi?id=196709
Reported-by: JianhongYin <yin-jianhong@163.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 fs/nfs/pagelist.c |   73 ++++++++++++++++++++++++++++--------------------------
 1 file changed, 39 insertions(+), 34 deletions(-)

--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -712,9 +712,6 @@ void nfs_pageio_init(struct nfs_pageio_d
 		     int io_flags,
 		     gfp_t gfp_flags)
 {
-	struct nfs_pgio_mirror *new;
-	int i;
-
 	desc->pg_moreio = 0;
 	desc->pg_inode = inode;
 	desc->pg_ops = pg_ops;
@@ -730,21 +727,9 @@ void nfs_pageio_init(struct nfs_pageio_d
 	desc->pg_mirror_count = 1;
 	desc->pg_mirror_idx = 0;
 
-	if (pg_ops->pg_get_mirror_count) {
-		/* until we have a request, we don't have an lseg and no
-		 * idea how many mirrors there will be */
-		new = kcalloc(NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX,
-			      sizeof(struct nfs_pgio_mirror), gfp_flags);
-		desc->pg_mirrors_dynamic = new;
-		desc->pg_mirrors = new;
-
-		for (i = 0; i < NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX; i++)
-			nfs_pageio_mirror_init(&desc->pg_mirrors[i], bsize);
-	} else {
-		desc->pg_mirrors_dynamic = NULL;
-		desc->pg_mirrors = desc->pg_mirrors_static;
-		nfs_pageio_mirror_init(&desc->pg_mirrors[0], bsize);
-	}
+	desc->pg_mirrors_dynamic = NULL;
+	desc->pg_mirrors = desc->pg_mirrors_static;
+	nfs_pageio_mirror_init(&desc->pg_mirrors[0], bsize);
 }
 EXPORT_SYMBOL_GPL(nfs_pageio_init);
 
@@ -863,32 +848,52 @@ static int nfs_generic_pg_pgios(struct n
 	return ret;
 }
 
+static struct nfs_pgio_mirror *
+nfs_pageio_alloc_mirrors(struct nfs_pageio_descriptor *desc,
+		unsigned int mirror_count)
+{
+	struct nfs_pgio_mirror *ret;
+	unsigned int i;
+
+	kfree(desc->pg_mirrors_dynamic);
+	desc->pg_mirrors_dynamic = NULL;
+	if (mirror_count == 1)
+		return desc->pg_mirrors_static;
+	ret = kmalloc_array(mirror_count, sizeof(*ret), GFP_NOFS);
+	if (ret != NULL) {
+		for (i = 0; i < mirror_count; i++)
+			nfs_pageio_mirror_init(&ret[i], desc->pg_bsize);
+		desc->pg_mirrors_dynamic = ret;
+	}
+	return ret;
+}
+
 /*
  * nfs_pageio_setup_mirroring - determine if mirroring is to be used
  *				by calling the pg_get_mirror_count op
  */
-static int nfs_pageio_setup_mirroring(struct nfs_pageio_descriptor *pgio,
+static void nfs_pageio_setup_mirroring(struct nfs_pageio_descriptor *pgio,
 				       struct nfs_page *req)
 {
-	int mirror_count = 1;
-
-	if (!pgio->pg_ops->pg_get_mirror_count)
-		return 0;
+	unsigned int mirror_count = 1;
 
-	mirror_count = pgio->pg_ops->pg_get_mirror_count(pgio, req);
-
-	if (pgio->pg_error < 0)
-		return pgio->pg_error;
-
-	if (!mirror_count || mirror_count > NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX)
-		return -EINVAL;
+	if (pgio->pg_ops->pg_get_mirror_count)
+		mirror_count = pgio->pg_ops->pg_get_mirror_count(pgio, req);
+	if (mirror_count == pgio->pg_mirror_count || pgio->pg_error < 0)
+		return;
 
-	if (WARN_ON_ONCE(!pgio->pg_mirrors_dynamic))
-		return -EINVAL;
+	if (!mirror_count || mirror_count > NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX) {
+		pgio->pg_error = -EINVAL;
+		return;
+	}
 
+	pgio->pg_mirrors = nfs_pageio_alloc_mirrors(pgio, mirror_count);
+	if (pgio->pg_mirrors == NULL) {
+		pgio->pg_error = -ENOMEM;
+		pgio->pg_mirrors = pgio->pg_mirrors_static;
+		mirror_count = 1;
+	}
 	pgio->pg_mirror_count = mirror_count;
-
-	return 0;
 }
 
 /*

  parent reply	other threads:[~2017-09-12 17:04 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-12 16:59 [PATCH 4.13 00/27] 4.13.2-stable review Greg Kroah-Hartman
2017-09-12 16:59 ` [PATCH 4.13 02/27] mtd: nand: hynix: add support for 20nm NAND chips Greg Kroah-Hartman
2017-09-12 16:59 ` [PATCH 4.13 03/27] mtd: nand: mxc: Fix mxc_v1 ooblayout Greg Kroah-Hartman
2017-09-12 16:59 ` [PATCH 4.13 04/27] mtd: nand: qcom: fix read failure without complete bootchain Greg Kroah-Hartman
2017-09-12 16:59 ` [PATCH 4.13 05/27] mtd: nand: qcom: fix config error for BCH Greg Kroah-Hartman
2017-09-12 16:59 ` [PATCH 4.13 06/27] nvme-fabrics: generate spec-compliant UUID NQNs Greg Kroah-Hartman
2017-09-12 16:59 ` [PATCH 4.13 07/27] btrfs: resume qgroup rescan on rw remount Greg Kroah-Hartman
2017-09-12 16:59 ` [PATCH 4.13 08/27] rtlwifi: btcoexist: Fix breakage of ant_sel for rtl8723be Greg Kroah-Hartman
2017-09-12 16:59 ` [PATCH 4.13 09/27] rtlwifi: btcoexist: Fix antenna selection code Greg Kroah-Hartman
2017-09-12 16:59 ` [PATCH 4.13 10/27] radix-tree: must check __radix_tree_preload() return value Greg Kroah-Hartman
2017-09-12 16:59 ` [PATCH 4.13 11/27] brcmfmac: feature check for multi-scheduled scan fails on bcm4345 devices Greg Kroah-Hartman
2017-09-12 16:59 ` [PATCH 4.13 12/27] kselftests: timers: leap-a-day: Change default arguments to help test runs Greg Kroah-Hartman
2017-09-12 16:59 ` [PATCH 4.13 13/27] selftests: timers: Fix run_destructive_tests target to handle skipped tests Greg Kroah-Hartman
2017-09-12 16:59 ` [PATCH 4.13 14/27] selftests/x86/fsgsbase: Test selectors 1, 2, and 3 Greg Kroah-Hartman
2017-09-12 16:59 ` [PATCH 4.13 15/27] mm: kvfree the swap cluster info if the swap file is unsatisfactory Greg Kroah-Hartman
2017-09-12 16:59 ` [PATCH 4.13 16/27] mm/swapfile.c: fix swapon frontswap_map memory leak on error Greg Kroah-Hartman
2017-09-12 16:59 ` [PATCH 4.13 17/27] mm/sparse.c: fix typo in online_mem_sections Greg Kroah-Hartman
2017-09-12 16:59 ` [PATCH 4.13 18/27] mm/memory.c: fix mem_cgroup_oom_disable() call missing Greg Kroah-Hartman
2017-09-12 17:00 ` [PATCH 4.13 20/27] Revert "firmware: add sanity check on shutdown/suspend" Greg Kroah-Hartman
2017-09-12 17:20   ` Luis R. Rodriguez
2017-09-13  0:47     ` Greg Kroah-Hartman
2017-09-13  1:22       ` Luis R. Rodriguez
2017-09-13  1:40         ` Greg Kroah-Hartman
2017-09-13  4:11       ` Linus Torvalds
2017-09-13 18:38         ` Luis R. Rodriguez
2017-09-13 19:30           ` Linus Torvalds
2017-09-13 21:44             ` Luis R. Rodriguez
2017-09-12 17:00 ` [PATCH 4.13 21/27] rt2800: fix TX_PIN_CFG setting for non MT7620 chips Greg Kroah-Hartman
2017-09-12 17:00 ` [PATCH 4.13 22/27] Bluetooth: Properly check L2CAP config option output buffer length Greg Kroah-Hartman
2017-09-12 17:00 ` [PATCH 4.13 23/27] ARM64: dts: marvell: armada-37xx: Fix GIC maintenance interrupt Greg Kroah-Hartman
2017-09-12 17:00 ` [PATCH 4.13 24/27] ARM: 8692/1: mm: abort uaccess retries upon fatal signal Greg Kroah-Hartman
2017-09-12 17:00 ` [PATCH 4.13 25/27] NFS: Fix 2 use after free issues in the I/O code Greg Kroah-Hartman
2017-09-12 17:00 ` [PATCH 4.13 26/27] NFS: Sync the correct byte range during synchronous writes Greg Kroah-Hartman
2017-09-12 17:00 ` Greg Kroah-Hartman [this message]
2017-09-13  0:13 ` [PATCH 4.13 00/27] 4.13.2-stable review Shuah Khan
2017-09-13  0:57   ` Greg Kroah-Hartman
     [not found] ` <59b8666e.e2a9df0a.378a2.e18c@mx.google.com>
2017-09-13  1:03   ` Greg Kroah-Hartman
2017-09-13 22:16     ` Kevin Hilman
2017-09-13 14:35 ` Guenter Roeck
2017-09-13 19:01   ` Greg Kroah-Hartman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170912165310.765255596@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=trond.myklebust@primarydata.com \
    --cc=yin-jianhong@163.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.