diff options
author | Jeff Layton <jlayton@redhat.com> | 2012-03-21 09:52:08 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2012-03-26 11:49:48 -0400 |
commit | 813fd320c16691eac508fe350b4ee7362c6c4a56 (patch) | |
tree | 3ec14685fb13b2f5fba6ed1ce78e5e6bdb7c173e /fs/nfsd | |
parent | f3f8014862d813cca81a597c83bd1dbf0fb2b8f6 (diff) |
nfsd: add notifier to handle mount/unmount of rpc_pipefs sb
In the event that rpc_pipefs isn't mounted when nfsd starts, we
must register a notifier to handle creating the dentry once it
is mounted, and to remove the dentry on unmount.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/netns.h | 1 | ||||
-rw-r--r-- | fs/nfsd/nfs4recover.c | 44 | ||||
-rw-r--r-- | fs/nfsd/nfsctl.c | 9 |
3 files changed, 53 insertions, 1 deletions
diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h index 12e0cff435b4..66eac332bf8d 100644 --- a/fs/nfsd/netns.h +++ b/fs/nfsd/netns.h | |||
@@ -31,4 +31,5 @@ struct nfsd_net { | |||
31 | }; | 31 | }; |
32 | 32 | ||
33 | extern int nfsd_net_id; | 33 | extern int nfsd_net_id; |
34 | extern struct notifier_block nfsd4_cld_block; | ||
34 | #endif /* __NFSD_NETNS_H__ */ | 35 | #endif /* __NFSD_NETNS_H__ */ |
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index cec62ed2a064..6f13281635ba 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/crypto.h> | 38 | #include <linux/crypto.h> |
39 | #include <linux/sched.h> | 39 | #include <linux/sched.h> |
40 | #include <linux/fs.h> | 40 | #include <linux/fs.h> |
41 | #include <linux/module.h> | ||
41 | #include <net/net_namespace.h> | 42 | #include <net/net_namespace.h> |
42 | #include <linux/sunrpc/rpc_pipe_fs.h> | 43 | #include <linux/sunrpc/rpc_pipe_fs.h> |
43 | #include <linux/sunrpc/clnt.h> | 44 | #include <linux/sunrpc/clnt.h> |
@@ -982,3 +983,46 @@ nfsd4_record_grace_done(struct net *net, time_t boot_time) | |||
982 | if (client_tracking_ops) | 983 | if (client_tracking_ops) |
983 | client_tracking_ops->grace_done(net, boot_time); | 984 | client_tracking_ops->grace_done(net, boot_time); |
984 | } | 985 | } |
986 | |||
987 | static int | ||
988 | rpc_pipefs_event(struct notifier_block *nb, unsigned long event, void *ptr) | ||
989 | { | ||
990 | struct super_block *sb = ptr; | ||
991 | struct net *net = sb->s_fs_info; | ||
992 | struct nfsd_net *nn = net_generic(net, nfsd_net_id); | ||
993 | struct cld_net *cn = nn->cld_net; | ||
994 | struct dentry *dentry; | ||
995 | int ret = 0; | ||
996 | |||
997 | if (!try_module_get(THIS_MODULE)) | ||
998 | return 0; | ||
999 | |||
1000 | if (!cn) { | ||
1001 | module_put(THIS_MODULE); | ||
1002 | return 0; | ||
1003 | } | ||
1004 | |||
1005 | switch (event) { | ||
1006 | case RPC_PIPEFS_MOUNT: | ||
1007 | dentry = nfsd4_cld_register_sb(sb, cn->cn_pipe); | ||
1008 | if (IS_ERR(dentry)) { | ||
1009 | ret = PTR_ERR(dentry); | ||
1010 | break; | ||
1011 | } | ||
1012 | cn->cn_pipe->dentry = dentry; | ||
1013 | break; | ||
1014 | case RPC_PIPEFS_UMOUNT: | ||
1015 | if (cn->cn_pipe->dentry) | ||
1016 | nfsd4_cld_unregister_sb(cn->cn_pipe); | ||
1017 | break; | ||
1018 | default: | ||
1019 | ret = -ENOTSUPP; | ||
1020 | break; | ||
1021 | } | ||
1022 | module_put(THIS_MODULE); | ||
1023 | return ret; | ||
1024 | } | ||
1025 | |||
1026 | struct notifier_block nfsd4_cld_block = { | ||
1027 | .notifier_call = rpc_pipefs_event, | ||
1028 | }; | ||
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 141197e04703..dee6c1bb9ba8 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/sunrpc/clnt.h> | 13 | #include <linux/sunrpc/clnt.h> |
14 | #include <linux/sunrpc/gss_api.h> | 14 | #include <linux/sunrpc/gss_api.h> |
15 | #include <linux/sunrpc/gss_krb5_enctypes.h> | 15 | #include <linux/sunrpc/gss_krb5_enctypes.h> |
16 | #include <linux/sunrpc/rpc_pipe_fs.h> | ||
16 | #include <linux/module.h> | 17 | #include <linux/module.h> |
17 | 18 | ||
18 | #include "idmap.h" | 19 | #include "idmap.h" |
@@ -1136,9 +1137,12 @@ static int __init init_nfsd(void) | |||
1136 | int retval; | 1137 | int retval; |
1137 | printk(KERN_INFO "Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n"); | 1138 | printk(KERN_INFO "Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n"); |
1138 | 1139 | ||
1140 | retval = rpc_pipefs_notifier_register(&nfsd4_cld_block); | ||
1141 | if (retval) | ||
1142 | return retval; | ||
1139 | retval = register_pernet_subsys(&nfsd_net_ops); | 1143 | retval = register_pernet_subsys(&nfsd_net_ops); |
1140 | if (retval < 0) | 1144 | if (retval < 0) |
1141 | return retval; | 1145 | goto out_unregister_notifier; |
1142 | retval = nfsd4_init_slabs(); | 1146 | retval = nfsd4_init_slabs(); |
1143 | if (retval) | 1147 | if (retval) |
1144 | goto out_unregister_pernet; | 1148 | goto out_unregister_pernet; |
@@ -1181,6 +1185,8 @@ out_free_slabs: | |||
1181 | nfsd4_free_slabs(); | 1185 | nfsd4_free_slabs(); |
1182 | out_unregister_pernet: | 1186 | out_unregister_pernet: |
1183 | unregister_pernet_subsys(&nfsd_net_ops); | 1187 | unregister_pernet_subsys(&nfsd_net_ops); |
1188 | out_unregister_notifier: | ||
1189 | rpc_pipefs_notifier_unregister(&nfsd4_cld_block); | ||
1184 | return retval; | 1190 | return retval; |
1185 | } | 1191 | } |
1186 | 1192 | ||
@@ -1197,6 +1203,7 @@ static void __exit exit_nfsd(void) | |||
1197 | nfsd_fault_inject_cleanup(); | 1203 | nfsd_fault_inject_cleanup(); |
1198 | unregister_filesystem(&nfsd_fs_type); | 1204 | unregister_filesystem(&nfsd_fs_type); |
1199 | unregister_pernet_subsys(&nfsd_net_ops); | 1205 | unregister_pernet_subsys(&nfsd_net_ops); |
1206 | rpc_pipefs_notifier_unregister(&nfsd4_cld_block); | ||
1200 | } | 1207 | } |
1201 | 1208 | ||
1202 | MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>"); | 1209 | MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>"); |