SUNRPC: remove RPC client pipefs dentries after unregister
authorStanislav Kinsbursky <skinsbursky@parallels.com>
Wed, 11 Jan 2012 15:18:26 +0000 (19:18 +0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Tue, 31 Jan 2012 23:20:25 +0000 (18:20 -0500)
Without this patch we have races:

rpc_fill_super rpc_free_client
rpc_pipefs_event(MOUNT) rpc_remove_pipedir
spin_lock(&rpc_client_lock);
rpc_setup_pipedir_sb
spin_unlock(&rpc_client_lock);
spin_lock(&rpc_client_lock);
(remove from list)
spin_unlock(&rpc_client_lock);
MEAMORY LEAKED

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
net/sunrpc/clnt.c

index 41707450059273c55129312c0e18e20c42586a5a..c89ceb80fe87fa0c4650aecaa123af6d223bc31d 100644 (file)
@@ -578,7 +578,6 @@ rpc_free_client(struct rpc_clnt *clnt)
 {
        dprintk("RPC:       destroying %s client for %s\n",
                        clnt->cl_protname, clnt->cl_server);
-       rpc_clnt_remove_pipedir(clnt);
        if (clnt->cl_parent != clnt) {
                rpc_release_client(clnt->cl_parent);
                goto out_free;
@@ -587,6 +586,7 @@ rpc_free_client(struct rpc_clnt *clnt)
                kfree(clnt->cl_server);
 out_free:
        rpc_unregister_client(clnt);
+       rpc_clnt_remove_pipedir(clnt);
        rpc_free_iostats(clnt->cl_metrics);
        kfree(clnt->cl_principal);
        clnt->cl_metrics = NULL;