diff options
-rw-r--r-- | include/linux/sunrpc/auth.h | 2 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 10 | ||||
-rw-r--r-- | net/sunrpc/clnt.c | 69 | ||||
-rw-r--r-- | net/sunrpc/rpc_pipe.c | 19 | ||||
-rw-r--r-- | net/sunrpc/sunrpc.h | 2 |
5 files changed, 92 insertions, 10 deletions
diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h index 7874a8a56638..492a36d72829 100644 --- a/include/linux/sunrpc/auth.h +++ b/include/linux/sunrpc/auth.h | |||
@@ -99,6 +99,8 @@ struct rpc_authops { | |||
99 | 99 | ||
100 | struct rpc_cred * (*lookup_cred)(struct rpc_auth *, struct auth_cred *, int); | 100 | struct rpc_cred * (*lookup_cred)(struct rpc_auth *, struct auth_cred *, int); |
101 | struct rpc_cred * (*crcreate)(struct rpc_auth*, struct auth_cred *, int); | 101 | struct rpc_cred * (*crcreate)(struct rpc_auth*, struct auth_cred *, int); |
102 | int (*pipes_create)(struct rpc_auth *); | ||
103 | void (*pipes_destroy)(struct rpc_auth *); | ||
102 | }; | 104 | }; |
103 | 105 | ||
104 | struct rpc_credops { | 106 | struct rpc_credops { |
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 1a6fa9173519..9da2d837b512 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -762,8 +762,10 @@ static void gss_pipes_dentries_destroy(struct rpc_auth *auth) | |||
762 | struct gss_auth *gss_auth; | 762 | struct gss_auth *gss_auth; |
763 | 763 | ||
764 | gss_auth = container_of(auth, struct gss_auth, rpc_auth); | 764 | gss_auth = container_of(auth, struct gss_auth, rpc_auth); |
765 | rpc_unlink(gss_auth->pipe[0]->dentry); | 765 | if (gss_auth->pipe[0]->dentry) |
766 | rpc_unlink(gss_auth->pipe[1]->dentry); | 766 | rpc_unlink(gss_auth->pipe[0]->dentry); |
767 | if (gss_auth->pipe[1]->dentry) | ||
768 | rpc_unlink(gss_auth->pipe[1]->dentry); | ||
767 | } | 769 | } |
768 | 770 | ||
769 | static int gss_pipes_dentries_create(struct rpc_auth *auth) | 771 | static int gss_pipes_dentries_create(struct rpc_auth *auth) |
@@ -1614,7 +1616,9 @@ static const struct rpc_authops authgss_ops = { | |||
1614 | .create = gss_create, | 1616 | .create = gss_create, |
1615 | .destroy = gss_destroy, | 1617 | .destroy = gss_destroy, |
1616 | .lookup_cred = gss_lookup_cred, | 1618 | .lookup_cred = gss_lookup_cred, |
1617 | .crcreate = gss_create_cred | 1619 | .crcreate = gss_create_cred, |
1620 | .pipes_create = gss_pipes_dentries_create, | ||
1621 | .pipes_destroy = gss_pipes_dentries_destroy, | ||
1618 | }; | 1622 | }; |
1619 | 1623 | ||
1620 | static const struct rpc_credops gss_credops = { | 1624 | static const struct rpc_credops gss_credops = { |
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 90e82c5daeb6..417074500592 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -98,8 +98,11 @@ static void rpc_unregister_client(struct rpc_clnt *clnt) | |||
98 | 98 | ||
99 | static void __rpc_clnt_remove_pipedir(struct rpc_clnt *clnt) | 99 | static void __rpc_clnt_remove_pipedir(struct rpc_clnt *clnt) |
100 | { | 100 | { |
101 | if (clnt->cl_path.dentry) | 101 | if (clnt->cl_path.dentry) { |
102 | if (clnt->cl_auth && clnt->cl_auth->au_ops->pipes_destroy) | ||
103 | clnt->cl_auth->au_ops->pipes_destroy(clnt->cl_auth); | ||
102 | rpc_remove_client_dir(clnt->cl_path.dentry); | 104 | rpc_remove_client_dir(clnt->cl_path.dentry); |
105 | } | ||
103 | clnt->cl_path.dentry = NULL; | 106 | clnt->cl_path.dentry = NULL; |
104 | } | 107 | } |
105 | 108 | ||
@@ -181,6 +184,70 @@ rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name) | |||
181 | return 0; | 184 | return 0; |
182 | } | 185 | } |
183 | 186 | ||
187 | static int __rpc_pipefs_event(struct rpc_clnt *clnt, unsigned long event, | ||
188 | struct super_block *sb) | ||
189 | { | ||
190 | struct dentry *dentry; | ||
191 | int err = 0; | ||
192 | |||
193 | switch (event) { | ||
194 | case RPC_PIPEFS_MOUNT: | ||
195 | if (clnt->cl_program->pipe_dir_name == NULL) | ||
196 | break; | ||
197 | dentry = rpc_setup_pipedir_sb(sb, clnt, | ||
198 | clnt->cl_program->pipe_dir_name); | ||
199 | BUG_ON(dentry == NULL); | ||
200 | if (IS_ERR(dentry)) | ||
201 | return PTR_ERR(dentry); | ||
202 | clnt->cl_path.dentry = dentry; | ||
203 | if (clnt->cl_auth->au_ops->pipes_create) { | ||
204 | err = clnt->cl_auth->au_ops->pipes_create(clnt->cl_auth); | ||
205 | if (err) | ||
206 | __rpc_clnt_remove_pipedir(clnt); | ||
207 | } | ||
208 | break; | ||
209 | case RPC_PIPEFS_UMOUNT: | ||
210 | __rpc_clnt_remove_pipedir(clnt); | ||
211 | break; | ||
212 | default: | ||
213 | printk(KERN_ERR "%s: unknown event: %ld\n", __func__, event); | ||
214 | return -ENOTSUPP; | ||
215 | } | ||
216 | return err; | ||
217 | } | ||
218 | |||
219 | static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event, | ||
220 | void *ptr) | ||
221 | { | ||
222 | struct super_block *sb = ptr; | ||
223 | struct rpc_clnt *clnt; | ||
224 | int error = 0; | ||
225 | struct sunrpc_net *sn = net_generic(sb->s_fs_info, sunrpc_net_id); | ||
226 | |||
227 | spin_lock(&sn->rpc_client_lock); | ||
228 | list_for_each_entry(clnt, &sn->all_clients, cl_clients) { | ||
229 | error = __rpc_pipefs_event(clnt, event, sb); | ||
230 | if (error) | ||
231 | break; | ||
232 | } | ||
233 | spin_unlock(&sn->rpc_client_lock); | ||
234 | return error; | ||
235 | } | ||
236 | |||
237 | static struct notifier_block rpc_clients_block = { | ||
238 | .notifier_call = rpc_pipefs_event, | ||
239 | }; | ||
240 | |||
241 | int rpc_clients_notifier_register(void) | ||
242 | { | ||
243 | return rpc_pipefs_notifier_register(&rpc_clients_block); | ||
244 | } | ||
245 | |||
246 | void rpc_clients_notifier_unregister(void) | ||
247 | { | ||
248 | return rpc_pipefs_notifier_unregister(&rpc_clients_block); | ||
249 | } | ||
250 | |||
184 | static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt) | 251 | static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt) |
185 | { | 252 | { |
186 | struct rpc_program *program = args->program; | 253 | struct rpc_program *program = args->program; |
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 6dd8b96e8df7..910de4169a8d 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
@@ -937,7 +937,7 @@ struct dentry *rpc_create_client_dir(struct dentry *dentry, | |||
937 | 937 | ||
938 | /** | 938 | /** |
939 | * rpc_remove_client_dir - Remove a directory created with rpc_create_client_dir() | 939 | * rpc_remove_client_dir - Remove a directory created with rpc_create_client_dir() |
940 | * @dentry: directory to remove | 940 | * @clnt: rpc client |
941 | */ | 941 | */ |
942 | int rpc_remove_client_dir(struct dentry *dentry) | 942 | int rpc_remove_client_dir(struct dentry *dentry) |
943 | { | 943 | { |
@@ -1188,17 +1188,24 @@ int register_rpc_pipefs(void) | |||
1188 | init_once); | 1188 | init_once); |
1189 | if (!rpc_inode_cachep) | 1189 | if (!rpc_inode_cachep) |
1190 | return -ENOMEM; | 1190 | return -ENOMEM; |
1191 | err = rpc_clients_notifier_register(); | ||
1192 | if (err) | ||
1193 | goto err_notifier; | ||
1191 | err = register_filesystem(&rpc_pipe_fs_type); | 1194 | err = register_filesystem(&rpc_pipe_fs_type); |
1192 | if (err) { | 1195 | if (err) |
1193 | kmem_cache_destroy(rpc_inode_cachep); | 1196 | goto err_register; |
1194 | return err; | ||
1195 | } | ||
1196 | |||
1197 | return 0; | 1197 | return 0; |
1198 | |||
1199 | err_register: | ||
1200 | rpc_clients_notifier_unregister(); | ||
1201 | err_notifier: | ||
1202 | kmem_cache_destroy(rpc_inode_cachep); | ||
1203 | return err; | ||
1198 | } | 1204 | } |
1199 | 1205 | ||
1200 | void unregister_rpc_pipefs(void) | 1206 | void unregister_rpc_pipefs(void) |
1201 | { | 1207 | { |
1208 | rpc_clients_notifier_unregister(); | ||
1202 | kmem_cache_destroy(rpc_inode_cachep); | 1209 | kmem_cache_destroy(rpc_inode_cachep); |
1203 | unregister_filesystem(&rpc_pipe_fs_type); | 1210 | unregister_filesystem(&rpc_pipe_fs_type); |
1204 | } | 1211 | } |
diff --git a/net/sunrpc/sunrpc.h b/net/sunrpc/sunrpc.h index 90c292e2738b..14c9f6d1c5ff 100644 --- a/net/sunrpc/sunrpc.h +++ b/net/sunrpc/sunrpc.h | |||
@@ -47,5 +47,7 @@ int svc_send_common(struct socket *sock, struct xdr_buf *xdr, | |||
47 | struct page *headpage, unsigned long headoffset, | 47 | struct page *headpage, unsigned long headoffset, |
48 | struct page *tailpage, unsigned long tailoffset); | 48 | struct page *tailpage, unsigned long tailoffset); |
49 | 49 | ||
50 | int rpc_clients_notifier_register(void); | ||
51 | void rpc_clients_notifier_unregister(void); | ||
50 | #endif /* _NET_SUNRPC_SUNRPC_H */ | 52 | #endif /* _NET_SUNRPC_SUNRPC_H */ |
51 | 53 | ||