From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: From: Sasha Levin To: "linux-kernel@vger.kernel.org" , "stable@vger.kernel.org" CC: "J. Bruce Fields" , Sasha Levin Subject: [PATCH AUTOSEL for 3.18 008/102] lockd: fix lockd shutdown race Date: Mon, 19 Mar 2018 16:11:33 +0000 Message-ID: <20180319161117.17833-8-alexander.levin@microsoft.com> References: <20180319161117.17833-1-alexander.levin@microsoft.com> In-Reply-To: <20180319161117.17833-1-alexander.levin@microsoft.com> Content-Language: en-US Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org List-ID: From: "J. Bruce Fields" [ Upstream commit efda760fe95ea15291853c8fa9235c32d319cd98 ] As reported by David Jeffery: "a signal was sent to lockd while lockd was shutting down from a request to stop nfs. The signal causes lockd to call restart_grace() which puts the lockd_net structure on the grace list. If this signal is received at the wrong time, it will occur after lockd_down_net() has called locks_end_grace() but before lockd_down_net() stops the lockd thread. This leads to lockd putting the lockd_net structure back on the grace list, then exiting without anything removing it from the list." So, perform the final locks_end_grace() from the the lockd thread; this ensures it's serialized with respect to restart_grace(). Reported-by: David Jeffery Signed-off-by: J. Bruce Fields Signed-off-by: Sasha Levin --- fs/lockd/svc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 61024987f97b..12d339ee6e06 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -129,6 +129,8 @@ lockd(void *vrqstp) { int err =3D 0; struct svc_rqst *rqstp =3D vrqstp; + struct net *net =3D &init_net; + struct lockd_net *ln =3D net_generic(net, lockd_net_id); =20 /* try_to_freeze() is called from svc_recv() */ set_freezable(); @@ -173,6 +175,8 @@ lockd(void *vrqstp) if (nlmsvc_ops) nlmsvc_invalidate_all(); nlm_shutdown_hosts(); + cancel_delayed_work_sync(&ln->grace_period_end); + locks_end_grace(&ln->lockd_manager); return 0; } =20 @@ -267,8 +271,6 @@ static void lockd_down_net(struct svc_serv *serv, struc= t net *net) if (ln->nlmsvc_users) { if (--ln->nlmsvc_users =3D=3D 0) { nlm_shutdown_hosts_net(net); - cancel_delayed_work_sync(&ln->grace_period_end); - locks_end_grace(&ln->lockd_manager); svc_shutdown_net(serv, net); dprintk("lockd_down_net: per-net data destroyed; net=3D%p\n", net); } --=20 2.14.1