diff options
-rw-r--r-- | include/linux/sunrpc/rpc_pipe_fs.h | 3 | ||||
-rw-r--r-- | net/sunrpc/netns.h | 1 | ||||
-rw-r--r-- | net/sunrpc/rpc_pipe.c | 36 | ||||
-rw-r--r-- | net/sunrpc/sunrpc_syms.c | 1 |
4 files changed, 41 insertions, 0 deletions
diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h index 2f3382230141..c13fca34dc9c 100644 --- a/include/linux/sunrpc/rpc_pipe_fs.h +++ b/include/linux/sunrpc/rpc_pipe_fs.h | |||
@@ -53,6 +53,9 @@ enum { | |||
53 | 53 | ||
54 | extern struct dentry *rpc_d_lookup_sb(const struct super_block *sb, | 54 | extern struct dentry *rpc_d_lookup_sb(const struct super_block *sb, |
55 | const unsigned char *dir_name); | 55 | const unsigned char *dir_name); |
56 | extern void rpc_pipefs_init_net(struct net *net); | ||
57 | extern struct super_block *rpc_get_sb_net(const struct net *net); | ||
58 | extern void rpc_put_sb_net(const struct net *net); | ||
56 | 59 | ||
57 | extern ssize_t rpc_pipe_generic_upcall(struct file *, struct rpc_pipe_msg *, | 60 | extern ssize_t rpc_pipe_generic_upcall(struct file *, struct rpc_pipe_msg *, |
58 | char __user *, size_t); | 61 | char __user *, size_t); |
diff --git a/net/sunrpc/netns.h b/net/sunrpc/netns.h index b3842529aec9..11d2f4863403 100644 --- a/net/sunrpc/netns.h +++ b/net/sunrpc/netns.h | |||
@@ -11,6 +11,7 @@ struct sunrpc_net { | |||
11 | struct cache_detail *ip_map_cache; | 11 | struct cache_detail *ip_map_cache; |
12 | 12 | ||
13 | struct super_block *pipefs_sb; | 13 | struct super_block *pipefs_sb; |
14 | struct mutex pipefs_sb_lock; | ||
14 | }; | 15 | }; |
15 | 16 | ||
16 | extern int sunrpc_net_id; | 17 | extern int sunrpc_net_id; |
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 | } |
1024 | EXPORT_SYMBOL_GPL(rpc_d_lookup_sb); | 1024 | EXPORT_SYMBOL_GPL(rpc_d_lookup_sb); |
1025 | 1025 | ||
1026 | void 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 | */ | ||
1039 | struct 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 | } | ||
1049 | EXPORT_SYMBOL_GPL(rpc_get_sb_net); | ||
1050 | |||
1051 | void 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 | } | ||
1058 | EXPORT_SYMBOL_GPL(rpc_put_sb_net); | ||
1059 | |||
1026 | static int | 1060 | static int |
1027 | rpc_fill_super(struct super_block *sb, void *data, int silent) | 1061 | rpc_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, |
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c index 8ec9778c3f4a..7086d11589c8 100644 --- a/net/sunrpc/sunrpc_syms.c +++ b/net/sunrpc/sunrpc_syms.c | |||
@@ -38,6 +38,7 @@ static __net_init int sunrpc_init_net(struct net *net) | |||
38 | if (err) | 38 | if (err) |
39 | goto err_ipmap; | 39 | goto err_ipmap; |
40 | 40 | ||
41 | rpc_pipefs_init_net(net); | ||
41 | return 0; | 42 | return 0; |
42 | 43 | ||
43 | err_ipmap: | 44 | err_ipmap: |