From patchwork Mon Aug 26 15:06:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13778008 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 494A31E892; Mon, 26 Aug 2024 15:07:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724684836; cv=none; b=P42DdYZubNCaa89gJCv5/CM56/s09gJIf+UPz0bVRkLTvG4oanWcKQMlD5+Rim/kfCUf9k42ANcTrA9/yiZ8QM3y9XOEXrGEp1cf3uy9PJ8/goiOf+rtQx5MHO4iXlsUfZSR9Iihcmn0hVfVcocyesVxqqrCm6/GQIzBmR7krXg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724684836; c=relaxed/simple; bh=AZj3YNOJX/H2yzVlv7P38vsSXbzbZ4ihmsnOm8GVBqk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=D6N1zs9IQU2dTgBm/mJZ7lrRYJx0kS98fpvjoxMpG+89Pz7p/mXm0NhKwG+2CbcwaoET9ZFtTS1gc9UlDf/Ewx2u/jWUqK3Qjk/W9JYfyCYjgudFm6tW01PZNlO04C7ZrwqqjD2/SUJb2j2+G0JNuZTZUqFJgVNd+/vxl00sfag= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=c+6Ba1iN; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="c+6Ba1iN" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6D64BC4FF18; Mon, 26 Aug 2024 15:07:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724684835; bh=AZj3YNOJX/H2yzVlv7P38vsSXbzbZ4ihmsnOm8GVBqk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=c+6Ba1iNZNqdVNUbp0viIZ2sJUKeS4mgEv4bIYaQGjU3FBdZ9Pic3kBluQegskXqm 930myzFov3TGJycTZ+SMuSV83BtMV9FoMUBFayTgNKUcTVscEpoar1zBZE27svKovk I5J4QEXfsLMqyglJ/rUQBDjFNJxeqau7K+qmgfYlKnZCMyCmFxgJdIW/hO5ps30+UQ pwt89FhE5GTQOuFiBAWxRNJj8IwGQJb/hjePZ14amzSrLgZG722W4BlosX/L0WchRQ Lm6eKcEtBFuasqhdcweT/G0Smw/oGdK93gJ4aqWdnrn+kWNBQK9uDsAJs5athGb8P2 EBLmXXkz0ykVA== From: cel@kernel.org To: Cc: , lilingfeng3@huawei.com, NeilBrown Subject: [PATCH 6.1.y 1/7] nfsd: Simplify code around svc_exit_thread() call in nfsd() Date: Mon, 26 Aug 2024 11:06:57 -0400 Message-ID: <20240826150703.13987-2-cel@kernel.org> X-Mailer: git-send-email 2.45.1 In-Reply-To: <20240826150703.13987-1-cel@kernel.org> References: <20240826150703.13987-1-cel@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: NeilBrown [ Upstream commit 18e4cf915543257eae2925671934937163f5639b ] Previously a thread could exit asynchronously (due to a signal) so some care was needed to hold nfsd_mutex over the last svc_put() call. Now a thread can only exit when svc_set_num_threads() is called, and this is always called under nfsd_mutex. So no care is needed. Not only is the mutex held when a thread exits now, but the svc refcount is elevated, so the svc_put() in svc_exit_thread() will never be a final put, so the mutex isn't even needed at this point in the code. Signed-off-by: NeilBrown Signed-off-by: Chuck Lever --- fs/nfsd/nfssvc.c | 23 ----------------------- include/linux/sunrpc/svc.h | 13 ------------- 2 files changed, 36 deletions(-) diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 9eb529969b22..3e120633ec86 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -983,31 +983,8 @@ nfsd(void *vrqstp) atomic_dec(&nfsd_th_cnt); out: - /* Take an extra ref so that the svc_put in svc_exit_thread() - * doesn't call svc_destroy() - */ - svc_get(nn->nfsd_serv); - /* Release the thread */ svc_exit_thread(rqstp); - - /* We need to drop a ref, but may not drop the last reference - * without holding nfsd_mutex, and we cannot wait for nfsd_mutex as that - * could deadlock with nfsd_shutdown_threads() waiting for us. - * So three options are: - * - drop a non-final reference, - * - get the mutex without waiting - * - sleep briefly andd try the above again - */ - while (!svc_put_not_last(nn->nfsd_serv)) { - if (mutex_trylock(&nfsd_mutex)) { - nfsd_put(net); - mutex_unlock(&nfsd_mutex); - break; - } - msleep(20); - } - return 0; } diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 912da376ef9b..49621cc4e01b 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -123,19 +123,6 @@ static inline void svc_put(struct svc_serv *serv) kref_put(&serv->sv_refcnt, svc_destroy); } -/** - * svc_put_not_last - decrement non-final reference count on SUNRPC serv - * @serv: the svc_serv to have count decremented - * - * Returns: %true is refcount was decremented. - * - * If the refcount is 1, it is not decremented and instead failure is reported. - */ -static inline bool svc_put_not_last(struct svc_serv *serv) -{ - return refcount_dec_not_one(&serv->sv_refcnt.refcount); -} - /* * Maximum payload size supported by a kernel RPC server. * This is use to determine the max number of pages nfsd is From patchwork Mon Aug 26 15:06:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13778009 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4092D13B286; Mon, 26 Aug 2024 15:07:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724684846; cv=none; b=KjsgtE71te+VDnch0YKZrCuAWT7MMXEk0ekUx5pbFXgLv0xSjwYmz6Pn+wASH4xG4IJX3M8i8x4qVBGHf2o7PM+a/M2iLdch9xNONm0g2ZW9rAKIcATilrgGMevoCLCY4yYahviZ7bSYujnXPvnNivS58nMMYFT6P9PxyVmEZ64= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724684846; c=relaxed/simple; bh=EV76P460T+1pji3RrIGaF7TEYj3nQmwwFjWIfFW+gcA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=r7ubPzuu5vJi+tL9iUaYQbxZ47ZvwMZii8vRhjAOngESlgCBobe6/q0CEaIMCoe5j7vOmkAWqVmsMUo58u24MR+X82jgIRCtd9NCykAibAj1hG6lRPoYU0rZpF9ayFkgk563lGZMeLIHMCGmW5D8z7WhaRriX3/A08SWtX9ILX4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rqC30F7G; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="rqC30F7G" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6F31FC4FF1B; Mon, 26 Aug 2024 15:07:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724684845; bh=EV76P460T+1pji3RrIGaF7TEYj3nQmwwFjWIfFW+gcA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rqC30F7GCY3dGJpb4jDyDee+zPbwcyXU4aQBaUmXeBVLCW9K4CGCMnNTTPmfS6V7d HSl1ozyLvrfTOK2BavOusxdh3s1rWNlAV6mwv6o6rTDRTczsxSYHW0J1Fne1GN7je9 Uro6fIlAzo/Upak2TPvWZsc/nHmf31ZmPZ5nnX1EGiold95fsZI+iECx/eXyyw1ROx cFDYhvZYxfRqc3xSrsJjn9INuHyj0EuuMO7XkcWxxjxfJ87lg5tZanKjGEcnDP3Uqg 8sRHYRHwLU4lahe7NST83RAg1qZS3SAQ8ZL3snZ+Xx+aDWVNzP8p3SFriz++SHXGPC VwJllTsXCpa9A== From: cel@kernel.org To: Cc: , lilingfeng3@huawei.com, NeilBrown Subject: [PATCH 6.1.y 2/7] nfsd: separate nfsd_last_thread() from nfsd_put() Date: Mon, 26 Aug 2024 11:06:58 -0400 Message-ID: <20240826150703.13987-3-cel@kernel.org> X-Mailer: git-send-email 2.45.1 In-Reply-To: <20240826150703.13987-1-cel@kernel.org> References: <20240826150703.13987-1-cel@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: NeilBrown [ Upstream commit 9f28a971ee9fdf1bf8ce8c88b103f483be610277 ] Now that the last nfsd thread is stopped by an explicit act of calling svc_set_num_threads() with a count of zero, we only have a limited number of places that can happen, and don't need to call nfsd_last_thread() in nfsd_put() So separate that out and call it at the two places where the number of threads is set to zero. Move the clearing of ->nfsd_serv and the call to svc_xprt_destroy_all() into nfsd_last_thread(), as they are really part of the same action. nfsd_put() is now a thin wrapper around svc_put(), so make it a static inline. nfsd_put() cannot be called after nfsd_last_thread(), so in a couple of places we have to use svc_put() instead. Signed-off-by: NeilBrown Signed-off-by: Chuck Lever --- fs/nfsd/nfsd.h | 7 ++++++- fs/nfsd/nfssvc.c | 52 ++++++++++++++++++------------------------------ 2 files changed, 25 insertions(+), 34 deletions(-) diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h index 0e557fb60a0e..18bfeb67cd1c 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h @@ -97,7 +97,12 @@ int nfsd_pool_stats_open(struct inode *, struct file *); int nfsd_pool_stats_release(struct inode *, struct file *); void nfsd_shutdown_threads(struct net *net); -void nfsd_put(struct net *net); +static inline void nfsd_put(struct net *net) +{ + struct nfsd_net *nn = net_generic(net, nfsd_net_id); + + svc_put(nn->nfsd_serv); +} bool i_am_nfsd(void); diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 3e120633ec86..4a86bfc31531 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -532,9 +532,14 @@ static struct notifier_block nfsd_inet6addr_notifier = { /* Only used under nfsd_mutex, so this atomic may be overkill: */ static atomic_t nfsd_notifier_refcount = ATOMIC_INIT(0); -static void nfsd_last_thread(struct svc_serv *serv, struct net *net) +static void nfsd_last_thread(struct net *net) { struct nfsd_net *nn = net_generic(net, nfsd_net_id); + struct svc_serv *serv = nn->nfsd_serv; + + spin_lock(&nfsd_notifier_lock); + nn->nfsd_serv = NULL; + spin_unlock(&nfsd_notifier_lock); /* check if the notifier still has clients */ if (atomic_dec_return(&nfsd_notifier_refcount) == 0) { @@ -544,6 +549,8 @@ static void nfsd_last_thread(struct svc_serv *serv, struct net *net) #endif } + svc_xprt_destroy_all(serv, net); + /* * write_ports can create the server without actually starting * any threads--if we get shut down before any threads are @@ -634,7 +641,8 @@ void nfsd_shutdown_threads(struct net *net) svc_get(serv); /* Kill outstanding nfsd threads */ svc_set_num_threads(serv, NULL, 0); - nfsd_put(net); + nfsd_last_thread(net); + svc_put(serv); mutex_unlock(&nfsd_mutex); } @@ -665,9 +673,6 @@ int nfsd_create_serv(struct net *net) serv->sv_maxconn = nn->max_connections; error = svc_bind(serv, net); if (error < 0) { - /* NOT nfsd_put() as notifiers (see below) haven't - * been set up yet. - */ svc_put(serv); return error; } @@ -710,29 +715,6 @@ int nfsd_get_nrthreads(int n, int *nthreads, struct net *net) return 0; } -/* This is the callback for kref_put() below. - * There is no code here as the first thing to be done is - * call svc_shutdown_net(), but we cannot get the 'net' from - * the kref. So do all the work when kref_put returns true. - */ -static void nfsd_noop(struct kref *ref) -{ -} - -void nfsd_put(struct net *net) -{ - struct nfsd_net *nn = net_generic(net, nfsd_net_id); - - if (kref_put(&nn->nfsd_serv->sv_refcnt, nfsd_noop)) { - svc_xprt_destroy_all(nn->nfsd_serv, net); - nfsd_last_thread(nn->nfsd_serv, net); - svc_destroy(&nn->nfsd_serv->sv_refcnt); - spin_lock(&nfsd_notifier_lock); - nn->nfsd_serv = NULL; - spin_unlock(&nfsd_notifier_lock); - } -} - int nfsd_set_nrthreads(int n, int *nthreads, struct net *net) { int i = 0; @@ -783,7 +765,7 @@ int nfsd_set_nrthreads(int n, int *nthreads, struct net *net) if (err) break; } - nfsd_put(net); + svc_put(nn->nfsd_serv); return err; } @@ -798,6 +780,7 @@ nfsd_svc(int nrservs, struct net *net, const struct cred *cred) int error; bool nfsd_up_before; struct nfsd_net *nn = net_generic(net, nfsd_net_id); + struct svc_serv *serv; mutex_lock(&nfsd_mutex); dprintk("nfsd: creating service\n"); @@ -817,22 +800,25 @@ nfsd_svc(int nrservs, struct net *net, const struct cred *cred) goto out; nfsd_up_before = nn->nfsd_net_up; + serv = nn->nfsd_serv; error = nfsd_startup_net(net, cred); if (error) goto out_put; - error = svc_set_num_threads(nn->nfsd_serv, NULL, nrservs); + error = svc_set_num_threads(serv, NULL, nrservs); if (error) goto out_shutdown; - error = nn->nfsd_serv->sv_nrthreads; + error = serv->sv_nrthreads; + if (error == 0) + nfsd_last_thread(net); out_shutdown: if (error < 0 && !nfsd_up_before) nfsd_shutdown_net(net); out_put: /* Threads now hold service active */ if (xchg(&nn->keep_active, 0)) - nfsd_put(net); - nfsd_put(net); + svc_put(serv); + svc_put(serv); out: mutex_unlock(&nfsd_mutex); return error; From patchwork Mon Aug 26 15:06:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13778010 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 53D481E892; Mon, 26 Aug 2024 15:07:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724684856; cv=none; b=YzsCpf2j6c9RVgg3rqYOEBXsiCJqGIUByBqdXXGaXSoVF5z+rjtpxJfHvu09IT00qrjK0EX3T++ApLRQhFwNq1gfEIPyL/7mdO1xGs6FOlIUdPCWgJu/kPg42m0tR2EjocHlysYJ1+3iU6/xZmIPdPstMav6CIKz1se6SAchh7I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724684856; c=relaxed/simple; bh=ijcVwqetnG5Qham1hBri0B96ZvtMq4TXAL+dPQw8mTI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MjuR9BV++XTFPBfoJZGicSCwekuUefXSubc5+TsiPy5Eci8qCb8vqeB3lZZHcUMVfItjimJXipeus5VMdMhYPgczqgw7VYuGGuuDKakq51UFTao+zP7NqDiiTfHD2zXQxGmpLj8hI840BuLCw3e1Hx6ZttnatP6K2YNjfugovco= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=LX6WgkTR; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="LX6WgkTR" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4C10DC4FF44; Mon, 26 Aug 2024 15:07:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724684855; bh=ijcVwqetnG5Qham1hBri0B96ZvtMq4TXAL+dPQw8mTI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LX6WgkTRgHj4cHp13f6ALb6pkD9kJVH0Mn2A92kE9G4XehDt+pzIXsbxXOqzrYQnY xkRCPk2gc0Z8ajw1RFOLDalHobIuMpXA9wWDQEnfsZbNJt8pBXQYFZ7qJSL2PivWKs VNcyDsjdV9BXrX+KTWcwMyqWgcMUwy2tKlbQMy8vCQzW5YUlXH5DghtcrPV0hczZfY 6Gh7hGWKmzKKNP6faATGkC1j3pZuxdKl9Hf2835KVxSZsFxSzbg+YMfqpXdRjf1DeG qBpHuZtuWiyTmwDH7AmIeNdQ4DZ934Xe/svaIC0wnqEuoeqTuUJaHW8Srl2mZhbHgp 1oxoEJEUppKoQ== From: cel@kernel.org To: Cc: , lilingfeng3@huawei.com, NeilBrown , Jeff Layton Subject: [PATCH 6.1.y 3/7] NFSD: simplify error paths in nfsd_svc() Date: Mon, 26 Aug 2024 11:06:59 -0400 Message-ID: <20240826150703.13987-4-cel@kernel.org> X-Mailer: git-send-email 2.45.1 In-Reply-To: <20240826150703.13987-1-cel@kernel.org> References: <20240826150703.13987-1-cel@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: NeilBrown [ Upstream commit bf32075256e9dd9c6b736859e2c5813981339908 ] The error paths in nfsd_svc() are needlessly complex and can result in a final call to svc_put() without nfsd_last_thread() being called. This results in the listening sockets not being closed properly. The per-netns setup provided by nfsd_startup_new() and removed by nfsd_shutdown_net() is needed precisely when there are running threads. So we don't need nfsd_up_before. We don't need to know if it *was* up. We only need to know if any threads are left. If none are, then we must call nfsd_shutdown_net(). But we don't need to do that explicitly as nfsd_last_thread() does that for us. So simply call nfsd_last_thread() before the last svc_put() if there are no running threads. That will always do the right thing. Also discard: pr_info("nfsd: last server has exited, flushing export cache\n"); It may not be true if an attempt to start the first server failed, and it isn't particularly helpful and it simply reports normal behaviour. Signed-off-by: NeilBrown Reviewed-by: Jeff Layton Signed-off-by: Chuck Lever --- fs/nfsd/nfssvc.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 4a86bfc31531..1d32fc985008 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -562,7 +562,6 @@ static void nfsd_last_thread(struct net *net) return; nfsd_shutdown_net(net); - pr_info("nfsd: last server has exited, flushing export cache\n"); nfsd_export_flush(net); } @@ -778,7 +777,6 @@ int nfsd_svc(int nrservs, struct net *net, const struct cred *cred) { int error; - bool nfsd_up_before; struct nfsd_net *nn = net_generic(net, nfsd_net_id); struct svc_serv *serv; @@ -798,8 +796,6 @@ nfsd_svc(int nrservs, struct net *net, const struct cred *cred) error = nfsd_create_serv(net); if (error) goto out; - - nfsd_up_before = nn->nfsd_net_up; serv = nn->nfsd_serv; error = nfsd_startup_net(net, cred); @@ -807,17 +803,15 @@ nfsd_svc(int nrservs, struct net *net, const struct cred *cred) goto out_put; error = svc_set_num_threads(serv, NULL, nrservs); if (error) - goto out_shutdown; + goto out_put; error = serv->sv_nrthreads; - if (error == 0) - nfsd_last_thread(net); -out_shutdown: - if (error < 0 && !nfsd_up_before) - nfsd_shutdown_net(net); out_put: /* Threads now hold service active */ if (xchg(&nn->keep_active, 0)) svc_put(serv); + + if (serv->sv_nrthreads == 0) + nfsd_last_thread(net); svc_put(serv); out: mutex_unlock(&nfsd_mutex); From patchwork Mon Aug 26 15:07:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13778017 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0D25613B286; Mon, 26 Aug 2024 15:07:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724684866; cv=none; b=V3uPVrJZFjm7sDKHLUXoS7pi/NLw0aNYg1HKKfpRQksdfijB9KLAKZtL6SfPnCPduijFO4rBDYCI4ArPiKYUS4chuDFuDlhejwq/oQSuEAojrlc0Vqb+TXqdqBqEsZIPMAu5lc+CCuELuaDDwvff1ZjJU2YeJyxGsJkDQC47m28= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724684866; c=relaxed/simple; bh=jjpYYlwaKLLkLBwEPkZHnlZc0qbcUfMFW2ounVGmNoI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kS0rzxHwuxC2KIWuavIYPLSDYHCsE0gzu5wUAH3fOlsM/iAo6R8XDeMdQx2FO2FCNH5LAx8HEy+u5h3vLWmJ9qbKWGKwCebtRdIecIirs3myQuOPzOcUWzWCCqAqLToBJFWiANqMd5NLkq/oqHVXUuvm5jOmCJDlGg2pn5K8gvA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=NA5vfwbt; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="NA5vfwbt" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 264B5C4FF53; Mon, 26 Aug 2024 15:07:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724684865; bh=jjpYYlwaKLLkLBwEPkZHnlZc0qbcUfMFW2ounVGmNoI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NA5vfwbtd1UMMlEJauZfYMk1R8oFqYaMLiclBzrLTfkqrN8NtAGM3X/6ZS8cdGHGN vwbfPG6ILSaDkNPsyiUv6DK8EUYKxaJYZdGf3AAZm5koX/FeFJKt5IAngIsPW0tqmz BeC33IdGISSlKm4mZjNC1OMrxbC+egXhjpkVNTjFhElPCwhIeYe5D4o7Qn6ns5dsRe /sw5e+nRS36ObFNcvhBf750nvLEfA4F1KvRgduuedcgEj8TkIdLwdpTCEx7xKJouBM x6jgRiDtJOxBzHe/fHObOcLakd9Ge7jVyq+KU03fp+mNXOmA1PWNZBKvupMTNBjR/w oVWcRYFtRtqZw== From: cel@kernel.org To: Cc: , lilingfeng3@huawei.com, NeilBrown , Jeff Layton Subject: [PATCH 6.1.y 4/7] nfsd: call nfsd_last_thread() before final nfsd_put() Date: Mon, 26 Aug 2024 11:07:00 -0400 Message-ID: <20240826150703.13987-5-cel@kernel.org> X-Mailer: git-send-email 2.45.1 In-Reply-To: <20240826150703.13987-1-cel@kernel.org> References: <20240826150703.13987-1-cel@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: NeilBrown [ Upstream commit 2a501f55cd641eb4d3c16a2eab0d678693fac663 ] If write_ports_addfd or write_ports_addxprt fail, they call nfsd_put() without calling nfsd_last_thread(). This leaves nn->nfsd_serv pointing to a structure that has been freed. So remove 'static' from nfsd_last_thread() and call it when the nfsd_serv is about to be destroyed. Fixes: ec52361df99b ("SUNRPC: stop using ->sv_nrthreads as a refcount") Signed-off-by: NeilBrown Reviewed-by: Jeff Layton Cc: Signed-off-by: Chuck Lever --- fs/nfsd/nfsctl.c | 9 +++++++-- fs/nfsd/nfsd.h | 1 + fs/nfsd/nfssvc.c | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 813ae75e7128..a906d0257e3a 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -720,8 +720,10 @@ static ssize_t __write_ports_addfd(char *buf, struct net *net, const struct cred err = svc_addsock(nn->nfsd_serv, net, fd, buf, SIMPLE_TRANSACTION_LIMIT, cred); - if (err >= 0 && - !nn->nfsd_serv->sv_nrthreads && !xchg(&nn->keep_active, 1)) + if (err < 0 && !nn->nfsd_serv->sv_nrthreads && !nn->keep_active) + nfsd_last_thread(net); + else if (err >= 0 && + !nn->nfsd_serv->sv_nrthreads && !xchg(&nn->keep_active, 1)) svc_get(nn->nfsd_serv); nfsd_put(net); @@ -771,6 +773,9 @@ static ssize_t __write_ports_addxprt(char *buf, struct net *net, const struct cr svc_xprt_put(xprt); } out_err: + if (!nn->nfsd_serv->sv_nrthreads && !nn->keep_active) + nfsd_last_thread(net); + nfsd_put(net); return err; } diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h index 18bfeb67cd1c..781781b88cca 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h @@ -139,6 +139,7 @@ int nfsd_vers(struct nfsd_net *nn, int vers, enum vers_op change); int nfsd_minorversion(struct nfsd_net *nn, u32 minorversion, enum vers_op change); void nfsd_reset_versions(struct nfsd_net *nn); int nfsd_create_serv(struct net *net); +void nfsd_last_thread(struct net *net); extern int nfsd_max_blksize; diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 1d32fc985008..80a2b3631adb 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -532,7 +532,7 @@ static struct notifier_block nfsd_inet6addr_notifier = { /* Only used under nfsd_mutex, so this atomic may be overkill: */ static atomic_t nfsd_notifier_refcount = ATOMIC_INIT(0); -static void nfsd_last_thread(struct net *net) +void nfsd_last_thread(struct net *net) { struct nfsd_net *nn = net_generic(net, nfsd_net_id); struct svc_serv *serv = nn->nfsd_serv; From patchwork Mon Aug 26 15:07:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13778018 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 67FCB13B286; Mon, 26 Aug 2024 15:07:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724684876; cv=none; b=LQ3OFdkGG5wmYfOB3+vxKB917d3DUj5BiY/Iv1NXOJBLDWHxuNKvWfb4lHCpziQvPmuYCdHfj+MfVwLrDj9VbrFlKXoBEecO6DfmbDUZeSvQTq3674nnpvEDPbgbwKnaKBijtm+NLfs9R5J2LYbZEZsESRj0EO/1OTCkiiKMHRQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724684876; c=relaxed/simple; bh=8UbVXFzGVjQE6pUMUlT0vADNlfUMBdxSVuclNT6eH/o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=r93sqWPTIsJxsZ8yGyOGTm9So3nhQSuEuexV2qwffxKKE/j6cNA8MfRB6eob1t2yYDjkmCUMmMFFDoBb8JWaD5QhR4pY1YywQlR3NCJoLXqB9Qf4P7zuN2y8eVZovmVUb3ewoYPVcWCZAjpL8aNpiNzAl6OEbX4eZ+mCiYabOPg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=q3V483mE; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="q3V483mE" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 59F22C4FF57; Mon, 26 Aug 2024 15:07:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724684875; bh=8UbVXFzGVjQE6pUMUlT0vADNlfUMBdxSVuclNT6eH/o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=q3V483mEtS+I30NLLft+zselEwz8ak+EBjTmxOnfjo7mvEKC6CdSgwD7pvhwjXzhi 6+wOIpADE3uCnThZ6Zamj1o3zd3CQMp7MvBlIEDhoItuVYNO7acRU2quK8fIQWZnYc R3GjW2ZXgZ2PfyRJuagO5Ltm97imXtmgZvjBMadjGH7zjk2LAosWQqD3vY78/MiLha 2JmifyAN1S6c+ImumrstsrD0OgYlN0yTZdiGIGJ++3wbRmOr9FyLGo+InMdBegHX5a YJwqwfzgPwUh50Ns+y/aybaCNE4sdJxdeNIHizySQzAgn1zsbh/3t6WXVlnlylWpMA o5rWOi28X583Q== From: cel@kernel.org To: Cc: , lilingfeng3@huawei.com, Jeff Layton , Zhi Li , NeilBrown Subject: [PATCH 6.1.y 5/7] nfsd: drop the nfsd_put helper Date: Mon, 26 Aug 2024 11:07:01 -0400 Message-ID: <20240826150703.13987-6-cel@kernel.org> X-Mailer: git-send-email 2.45.1 In-Reply-To: <20240826150703.13987-1-cel@kernel.org> References: <20240826150703.13987-1-cel@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Jeff Layton [ Upstream commit 64e6304169f1e1f078e7f0798033f80a7fb0ea46 ] It's not safe to call nfsd_put once nfsd_last_thread has been called, as that function will zero out the nn->nfsd_serv pointer. Drop the nfsd_put helper altogether and open-code the svc_put in its callers instead. That allows us to not be reliant on the value of that pointer when handling an error. Fixes: 2a501f55cd64 ("nfsd: call nfsd_last_thread() before final nfsd_put()") Reported-by: Zhi Li Cc: NeilBrown Signed-off-by: Jeffrey Layton Signed-off-by: Chuck Lever --- fs/nfsd/nfsctl.c | 31 +++++++++++++++++-------------- fs/nfsd/nfsd.h | 7 ------- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index a906d0257e3a..2feaa49fb9fe 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -709,6 +709,7 @@ static ssize_t __write_ports_addfd(char *buf, struct net *net, const struct cred char *mesg = buf; int fd, err; struct nfsd_net *nn = net_generic(net, nfsd_net_id); + struct svc_serv *serv; err = get_int(&mesg, &fd); if (err != 0 || fd < 0) @@ -718,15 +719,15 @@ static ssize_t __write_ports_addfd(char *buf, struct net *net, const struct cred if (err != 0) return err; - err = svc_addsock(nn->nfsd_serv, net, fd, buf, SIMPLE_TRANSACTION_LIMIT, cred); + serv = nn->nfsd_serv; + err = svc_addsock(serv, net, fd, buf, SIMPLE_TRANSACTION_LIMIT, cred); - if (err < 0 && !nn->nfsd_serv->sv_nrthreads && !nn->keep_active) + if (err < 0 && !serv->sv_nrthreads && !nn->keep_active) nfsd_last_thread(net); - else if (err >= 0 && - !nn->nfsd_serv->sv_nrthreads && !xchg(&nn->keep_active, 1)) - svc_get(nn->nfsd_serv); + else if (err >= 0 && !serv->sv_nrthreads && !xchg(&nn->keep_active, 1)) + svc_get(serv); - nfsd_put(net); + svc_put(serv); return err; } @@ -740,6 +741,7 @@ static ssize_t __write_ports_addxprt(char *buf, struct net *net, const struct cr struct svc_xprt *xprt; int port, err; struct nfsd_net *nn = net_generic(net, nfsd_net_id); + struct svc_serv *serv; if (sscanf(buf, "%15s %5u", transport, &port) != 2) return -EINVAL; @@ -751,32 +753,33 @@ static ssize_t __write_ports_addxprt(char *buf, struct net *net, const struct cr if (err != 0) return err; - err = svc_xprt_create(nn->nfsd_serv, transport, net, + serv = nn->nfsd_serv; + err = svc_xprt_create(serv, transport, net, PF_INET, port, SVC_SOCK_ANONYMOUS, cred); if (err < 0) goto out_err; - err = svc_xprt_create(nn->nfsd_serv, transport, net, + err = svc_xprt_create(serv, transport, net, PF_INET6, port, SVC_SOCK_ANONYMOUS, cred); if (err < 0 && err != -EAFNOSUPPORT) goto out_close; - if (!nn->nfsd_serv->sv_nrthreads && !xchg(&nn->keep_active, 1)) - svc_get(nn->nfsd_serv); + if (!serv->sv_nrthreads && !xchg(&nn->keep_active, 1)) + svc_get(serv); - nfsd_put(net); + svc_put(serv); return 0; out_close: - xprt = svc_find_xprt(nn->nfsd_serv, transport, net, PF_INET, port); + xprt = svc_find_xprt(serv, transport, net, PF_INET, port); if (xprt != NULL) { svc_xprt_close(xprt); svc_xprt_put(xprt); } out_err: - if (!nn->nfsd_serv->sv_nrthreads && !nn->keep_active) + if (!serv->sv_nrthreads && !nn->keep_active) nfsd_last_thread(net); - nfsd_put(net); + svc_put(serv); return err; } diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h index 781781b88cca..996f3f62335b 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h @@ -97,13 +97,6 @@ int nfsd_pool_stats_open(struct inode *, struct file *); int nfsd_pool_stats_release(struct inode *, struct file *); void nfsd_shutdown_threads(struct net *net); -static inline void nfsd_put(struct net *net) -{ - struct nfsd_net *nn = net_generic(net, nfsd_net_id); - - svc_put(nn->nfsd_serv); -} - bool i_am_nfsd(void); struct nfsdfs_client { From patchwork Mon Aug 26 15:07:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13778019 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0F4971E892; Mon, 26 Aug 2024 15:08:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724684886; cv=none; b=tIpeFNBzjgvPVN8b3iWFErhgyKReSbnAgXUIDAkja/FVyFLo4kDcZ3PfCXEHx5sX7mJT+d4iQdtgnQCXe/nxZ2dU2ptTy3wXy0OfejpsZAMR+rQ1oE786LnM4VyBPsuqjJcVu/E2E3fvmhjRWWwjG9UrKKXEc0NwLxla8ufc9d0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724684886; c=relaxed/simple; bh=cwXr5ZywFkrGFxSrYN5eRjdXXpMEQkmsJUMAF4W6IUg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=h/dTst59QYX8Y64i610pVx+iGw6EFsQD2JE/vuCPLtKDrXaDVtD3yvUh1S2a/YBuDdHGqJVa4zRmK15Xm4zYFnelemupzmm2XrBZnXf9vBCmpknwutNRlCFaoZID7eUP9EIWeRQWhc3SFT9i+QPAShZPnV0sywz4bU68QjdiIcE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ADOaHtMe; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ADOaHtMe" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 752B6C4FF61; Mon, 26 Aug 2024 15:08:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724684885; bh=cwXr5ZywFkrGFxSrYN5eRjdXXpMEQkmsJUMAF4W6IUg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ADOaHtMenhSD5L8yGvpw0I26JaVFIcn7wIWB3HzvIZvMy+/OtH2dAuNtzJwcMoFnw zE9EpUrs8HAR3wDXblTgyaIQQXdxX9lTgLp3g+h36gQW6Msu+Eb5pR6VlTeeKdHQbX J4iBgcVMIVUZLBDVhKwWXHkCCBT6+00dYOywM6b6HUBgZG0fK1KizF8mMRRiYz9aHC XPf53+XR4eqjmcdInfzo39BvDVXnjUT1l/Rw8oEmx7++EpiRR2gKXe7aXhePV4KmvU k5mwf53aJP4ZQ3BuQ0nolMuocP0RX7Y46GsKQENgg2thiV2h5epdH1TVjwujl7yKY4 5e6efXzUiSrAA== From: cel@kernel.org To: Cc: , lilingfeng3@huawei.com, NeilBrown Subject: [PATCH 6.1.y 6/7] nfsd: don't call locks_release_private() twice concurrently Date: Mon, 26 Aug 2024 11:07:02 -0400 Message-ID: <20240826150703.13987-7-cel@kernel.org> X-Mailer: git-send-email 2.45.1 In-Reply-To: <20240826150703.13987-1-cel@kernel.org> References: <20240826150703.13987-1-cel@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: NeilBrown [ Upstream commit 05eda6e75773592760285e10ac86c56d683be17f ] It is possible for free_blocked_lock() to be called twice concurrently, once from nfsd4_lock() and once from nfsd4_release_lockowner() calling remove_blocked_locks(). This is why a kref was added. It is perfectly safe for locks_delete_block() and kref_put() to be called in parallel as they use locking or atomicity respectively as protection. However locks_release_private() has no locking. It is safe for it to be called twice sequentially, but not concurrently. This patch moves that call from free_blocked_lock() where it could race with itself, to free_nbl() where it cannot. This will slightly delay the freeing of private info or release of the owner - but not by much. It is arguably more natural for this freeing to happen in free_nbl() where the structure itself is freed. This bug was found by code inspection - it has not been seen in practice. Fixes: 47446d74f170 ("nfsd4: add refcount for nfsd4_blocked_lock") Signed-off-by: NeilBrown Signed-off-by: Chuck Lever --- fs/nfsd/nfs4state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 8d15959004ad..f04de2553c90 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -318,6 +318,7 @@ free_nbl(struct kref *kref) struct nfsd4_blocked_lock *nbl; nbl = container_of(kref, struct nfsd4_blocked_lock, nbl_kref); + locks_release_private(&nbl->nbl_lock); kfree(nbl); } @@ -325,7 +326,6 @@ static void free_blocked_lock(struct nfsd4_blocked_lock *nbl) { locks_delete_block(&nbl->nbl_lock); - locks_release_private(&nbl->nbl_lock); kref_put(&nbl->nbl_kref, free_nbl); } From patchwork Mon Aug 26 15:07:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13778020 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8E8141E892; Mon, 26 Aug 2024 15:08:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724684896; cv=none; b=oHyX+KEgPKNN3LFryXakcfRsj1ZwpbPKoapL6LNoPUfFt2W/d5jz+ktNQxaN9qse9D7WnoEvM7pb4GVxWUkzXCmK2AReLhFoVK9y6up1BOAstWK+DBIgDwKYk/69o0HAsIePVBQuSns+3p7MmPdF5gyDs4uEhiT8iUDun5PjoiI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724684896; c=relaxed/simple; bh=nESy1bZKUzMFIPhgaxtlTbG62TuQTsA4+4HBKa5jyA8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BHKBjKc+Ja2Yr/zSUAZaXobIOFsnghNwe6Hyue0lHORCLq0dcOf4w+v0u6SyMxohTZ7M0V1fcqDfEYPoM6dF8Cp0e8+jhFYOwPZjAbUDp8gd390MKi43MaOsW1v6HIDGqvuTOfwjnjRs7ptrzsGrbjNaJ+tKtLZDcjH/0QaQ6UE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=HQfNrHAt; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="HQfNrHAt" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 673D5C4FF63; Mon, 26 Aug 2024 15:08:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724684896; bh=nESy1bZKUzMFIPhgaxtlTbG62TuQTsA4+4HBKa5jyA8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HQfNrHAtk8AkOioqLHT8fd475CbfwChsR0W1XjZMdXo7sDfi4+y8Io7a5npIilvaK 5NIEkTAAZ+vJbwL4fbxvQGkk1XSM8RBaviqHZ6ygkgd/bSCcpYofQhRAFFLeSAktAM +KHS9Jrblb0VSDRQBrtsUkjLzJ5mPxgwrTme9+2t6g2fVEyfmfa4Xis+xJBdQ424Iv pzip65JJXG+oYdl/vjGvs5GcgjckFIpU/zgqwDAGte2VeMTlx104KgrVj24QQp5lRi ap9U7KkrJWxJ2RduuT1MAj5YYfz9RgKSxGhWI8UAyGfEbnj8oFFPspC3msnA7NC8b2 aPsl4SLf/D69w== From: cel@kernel.org To: Cc: , lilingfeng3@huawei.com, Trond Myklebust , Jeff Layton , NeilBrown Subject: [PATCH 6.1.y 7/7] nfsd: Fix a regression in nfsd_setattr() Date: Mon, 26 Aug 2024 11:07:03 -0400 Message-ID: <20240826150703.13987-8-cel@kernel.org> X-Mailer: git-send-email 2.45.1 In-Reply-To: <20240826150703.13987-1-cel@kernel.org> References: <20240826150703.13987-1-cel@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Trond Myklebust [ Upstream commit 6412e44c40aaf8f1d7320b2099c5bdd6cb9126ac ] Commit bb4d53d66e4b ("NFSD: use (un)lock_inode instead of fh_(un)lock for file operations") broke the NFSv3 pre/post op attributes behaviour when doing a SETATTR rpc call by stripping out the calls to fh_fill_pre_attrs() and fh_fill_post_attrs(). Fixes: bb4d53d66e4b ("NFSD: use (un)lock_inode instead of fh_(un)lock for file operations") Signed-off-by: Trond Myklebust Reviewed-by: Jeff Layton Reviewed-by: NeilBrown Message-ID: <20240216012451.22725-1-trondmy@kernel.org> [ cel: adjusted to apply to v6.1.y ] Signed-off-by: Chuck Lever --- fs/nfsd/nfs4proc.c | 4 ++++ fs/nfsd/vfs.c | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 7451cd34710d..df9dbd93663e 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1106,6 +1106,7 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, }; struct inode *inode; __be32 status = nfs_ok; + bool save_no_wcc; int err; if (setattr->sa_iattr.ia_valid & ATTR_SIZE) { @@ -1131,8 +1132,11 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, if (status) goto out; + save_no_wcc = cstate->current_fh.fh_no_wcc; + cstate->current_fh.fh_no_wcc = true; status = nfsd_setattr(rqstp, &cstate->current_fh, &attrs, 0, (time64_t)0); + cstate->current_fh.fh_no_wcc = save_no_wcc; if (!status) status = nfserrno(attrs.na_labelerr); if (!status) diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 17e96e58e772..8f6d611d1380 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -475,7 +475,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, int accmode = NFSD_MAY_SATTR; umode_t ftype = 0; __be32 err; - int host_err; + int host_err = 0; bool get_write_count; bool size_change = (iap->ia_valid & ATTR_SIZE); int retries; @@ -533,6 +533,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, } inode_lock(inode); + fh_fill_pre_attrs(fhp); for (retries = 1;;) { struct iattr attrs; @@ -560,13 +561,14 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, attr->na_aclerr = set_posix_acl(&init_user_ns, inode, ACL_TYPE_DEFAULT, attr->na_dpacl); + fh_fill_post_attrs(fhp); inode_unlock(inode); if (size_change) put_write_access(inode); out: if (!host_err) host_err = commit_metadata(fhp); - return nfserrno(host_err); + return err != 0 ? err : nfserrno(host_err); } #if defined(CONFIG_NFSD_V4)