diff options
author | Stanislav Kinsbursky <skinsbursky@parallels.com> | 2013-06-24 11:52:38 +0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-06-28 15:41:18 -0400 |
commit | 384816051ca9125cd54750e59c780c2a2655fa4f (patch) | |
tree | b7ef1f57a54d747f750c2ad8c8974b236ff9febf /net/sunrpc/rpc_pipe.c | |
parent | 52fcac988ae6d5a902e9c1d79fc11ba5ec9361e7 (diff) | |
download | blackbird-op-linux-384816051ca9125cd54750e59c780c2a2655fa4f.tar.gz blackbird-op-linux-384816051ca9125cd54750e59c780c2a2655fa4f.zip |
SUNRPC: fix races on PipeFS MOUNT notifications
Below are races, when RPC client can be created without PiepFS dentries
CPU#0 CPU#1
----------------------------- -----------------------------
rpc_new_client rpc_fill_super
rpc_setup_pipedir
mutex_lock(&sn->pipefs_sb_lock)
rpc_get_sb_net == NULL
(no per-net PipeFS superblock)
sn->pipefs_sb = sb;
notifier_call_chain(MOUNT)
(client is not in the list)
rpc_register_client
(client without pipes dentries)
To fix this patch:
1) makes PipeFS mount notification call with pipefs_sb_lock being held.
2) releases pipefs_sb_lock on new SUNRPC client creation only after
registration.
Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
Cc: stable@vger.kernel.org
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc/rpc_pipe.c')
-rw-r--r-- | net/sunrpc/rpc_pipe.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index a816b3a69059..e02823bdfe98 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c @@ -1127,6 +1127,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent) return -ENOMEM; dprintk("RPC: sending pipefs MOUNT notification for net %p%s\n", net, NET_NAME(net)); + mutex_lock(&sn->pipefs_sb_lock); sn->pipefs_sb = sb; err = blocking_notifier_call_chain(&rpc_pipefs_notifier_list, RPC_PIPEFS_MOUNT, @@ -1134,6 +1135,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent) if (err) goto err_depopulate; sb->s_fs_info = get_net(net); + mutex_unlock(&sn->pipefs_sb_lock); return 0; err_depopulate: @@ -1142,6 +1144,7 @@ err_depopulate: sb); sn->pipefs_sb = NULL; __rpc_depopulate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF); + mutex_unlock(&sn->pipefs_sb_lock); return err; } |