aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/rpc_pipe.c
diff options
context:
space:
mode:
authorStanislav Kinsbursky <skinsbursky@parallels.com>2011-12-26 07:39:39 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-01-31 18:20:24 -0500
commitc21a588f35b1c50304e505fad542b3aab0814266 (patch)
tree2dda83e8d5f62eb9892c425941265aeeb278e952 /net/sunrpc/rpc_pipe.c
parent90c4e82999c517e0cd00d0782c68d186cb18b784 (diff)
SUNRPC: pipefs per-net operations helper introduced
During per-net pipes creation and destruction we have to make sure, that pipefs sb exists for the whole creation/destruction cycle. This is done by using special mutex which controls pipefs sb reference on network namespace context. Helper consists of two parts: first of them (rpc_get_dentry_net) searches for dentry with specified name and returns with mutex taken on success. When pipe creation or destructions is completed, caller should release this mutex by rpc_put_dentry_net call. Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc/rpc_pipe.c')
-rw-r--r--net/sunrpc/rpc_pipe.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index e5e1f357b561..f075f8817773 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -1023,6 +1023,40 @@ struct dentry *rpc_d_lookup_sb(const struct super_block *sb,
1023} 1023}
1024EXPORT_SYMBOL_GPL(rpc_d_lookup_sb); 1024EXPORT_SYMBOL_GPL(rpc_d_lookup_sb);
1025 1025
1026void rpc_pipefs_init_net(struct net *net)
1027{
1028 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
1029
1030 mutex_init(&sn->pipefs_sb_lock);
1031}
1032
1033/*
1034 * This call will be used for per network namespace operations calls.
1035 * Note: Function will be returned with pipefs_sb_lock taken if superblock was
1036 * found. This lock have to be released by rpc_put_sb_net() when all operations
1037 * will be completed.
1038 */
1039struct super_block *rpc_get_sb_net(const struct net *net)
1040{
1041 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
1042
1043 mutex_lock(&sn->pipefs_sb_lock);
1044 if (sn->pipefs_sb)
1045 return sn->pipefs_sb;
1046 mutex_unlock(&sn->pipefs_sb_lock);
1047 return NULL;
1048}
1049EXPORT_SYMBOL_GPL(rpc_get_sb_net);
1050
1051void rpc_put_sb_net(const struct net *net)
1052{
1053 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
1054
1055 BUG_ON(sn->pipefs_sb == NULL);
1056 mutex_unlock(&sn->pipefs_sb_lock);
1057}
1058EXPORT_SYMBOL_GPL(rpc_put_sb_net);
1059
1026static int 1060static int
1027rpc_fill_super(struct super_block *sb, void *data, int silent) 1061rpc_fill_super(struct super_block *sb, void *data, int silent)
1028{ 1062{
@@ -1077,7 +1111,9 @@ void rpc_kill_sb(struct super_block *sb)
1077 struct net *net = sb->s_fs_info; 1111 struct net *net = sb->s_fs_info;
1078 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 1112 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
1079 1113
1114 mutex_lock(&sn->pipefs_sb_lock);
1080 sn->pipefs_sb = NULL; 1115 sn->pipefs_sb = NULL;
1116 mutex_unlock(&sn->pipefs_sb_lock);
1081 put_net(net); 1117 put_net(net);
1082 blocking_notifier_call_chain(&rpc_pipefs_notifier_list, 1118 blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
1083 RPC_PIPEFS_UMOUNT, 1119 RPC_PIPEFS_UMOUNT,