[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1560341370-24197-4-git-send-email-wenbinzeng@tencent.com>
Date: Wed, 12 Jun 2019 20:09:30 +0800
From: Wenbin Zeng <wenbin.zeng@...il.com>
To: bfields@...ldses.org, davem@...emloft.net, viro@...iv.linux.org.uk
Cc: jlayton@...nel.org, trond.myklebust@...merspace.com,
anna.schumaker@...app.com, wenbinzeng@...cent.com,
dsahern@...il.com, nicolas.dichtel@...nd.com, willy@...radead.org,
edumazet@...gle.com, jakub.kicinski@...ronome.com,
tyhicks@...onical.com, chuck.lever@...cle.com, neilb@...e.com,
linux-fsdevel@...r.kernel.org, linux-kernel@...r.kernel.org,
netdev@...r.kernel.org, linux-nfs@...r.kernel.org,
"J. Bruce Fields" <bfields@...hat.com>
Subject: [PATCH v3 3/3] auth_gss: fix deadlock that blocks rpcsec_gss_exit_net when use-gss-proxy==1
When use-gss-proxy is set to 1, write_gssp() creates a rpc client in
gssp_rpc_create(), this increases netns refcount by 2, these refcounts are
supposed to be released in rpcsec_gss_exit_net(), but it will never happen
because rpcsec_gss_exit_net() is triggered only when netns refcount gets
to 0, specifically:
refcount=0 -> cleanup_net() -> ops_exit_list -> rpcsec_gss_exit_net
It is a deadlock situation here, refcount will never get to 0 unless
rpcsec_gss_exit_net() is called.
This fix introduced a new callback i.e. evict in struct proc_ns_operations,
which is called in nsfs_evict. Moving rpcsec_gss_exit_net to evict path
gives it a chance to get called and avoids the above deadlock situation.
Signed-off-by: Wenbin Zeng <wenbinzeng@...cent.com>
Cc: J. Bruce Fields <bfields@...hat.com>
---
net/sunrpc/auth_gss/auth_gss.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 3fd56c0..3e76c8a 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -2136,14 +2136,14 @@ static __net_init int rpcsec_gss_init_net(struct net *net)
return gss_svc_init_net(net);
}
-static __net_exit void rpcsec_gss_exit_net(struct net *net)
+static void rpcsec_gss_evict_net(struct net *net)
{
gss_svc_shutdown_net(net);
}
static struct pernet_operations rpcsec_gss_net_ops = {
.init = rpcsec_gss_init_net,
- .exit = rpcsec_gss_exit_net,
+ .evict = rpcsec_gss_evict_net,
};
/*
--
1.8.3.1
Powered by blists - more mailing lists