[PATCH] nfs: fix refcount leak in nfs_swap_activate()

WenTao Liang <[email protected]>
Newsgroups gmane.linux.nfs,gmane.linux.network,gmane.linux.kernel,gmane.linux.kernel.stable
Message-ID <[email protected]>
nfs_swap_activate() calls rpc_clnt_swap_activate(), which
unconditionally increments the cl_swapper refcount via
atomic_inc_return().  If the subsequent call to
rpc_clnt_iterate_for_each_xprt() fails (e.g. the callback
xprt_enable_swap() returns an error), rpc_clnt_swap_activate()
returns the error without decrementing the refcount.  Back in
nfs_swap_activate(), a nonzero return value is treated as a
fatal error and causes an immediate return, so the elevated
cl_swapper count is never released.

Fix this by adding an atomic_dec() in the error path of
rpc_clnt_swap_activate() before returning the error code, so
that a failed activation properly cleans up the refcount.

Cc: [email protected]
Fixes: 15001e5a7e1e ("SUNRPC: Make NFS swap work with multipath")
Signed-off-by: WenTao Liang <[email protected]>
---
 net/sunrpc/clnt.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index bc8ca470718b..97ab7aa71997 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -3396,9 +3396,13 @@ rpc_clnt_swap_activate(struct rpc_clnt *clnt)
 {
 	while (clnt != clnt->cl_parent)
 		clnt = clnt->cl_parent;
-	if (atomic_inc_return(&clnt->cl_swapper) == 1)
-		return rpc_clnt_iterate_for_each_xprt(clnt,
+	if (atomic_inc_return(&clnt->cl_swapper) == 1) {
+		int ret = rpc_clnt_iterate_for_each_xprt(clnt,
 				rpc_clnt_swap_activate_callback, NULL);
+		if (ret)
+			atomic_dec(&clnt->cl_swapper);
+		return ret;
+	}
 	return 0;
 }
 EXPORT_SYMBOL_GPL(rpc_clnt_swap_activate);
-- 
2.50.1 (Apple Git-155)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.