sunrpc: Make the /proc/net/rpc appear in net namespaces
authorPavel Emelyanov <xemul@parallels.com>
Mon, 27 Sep 2010 10:01:58 +0000 (14:01 +0400)
committerJ. Bruce Fields <bfields@redhat.com>
Mon, 27 Sep 2010 14:16:12 +0000 (10:16 -0400)
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
include/linux/sunrpc/stats.h
net/sunrpc/cache.c
net/sunrpc/netns.h
net/sunrpc/stats.c
net/sunrpc/sunrpc_syms.c

index 5fa0f20843078a94c8822ef1a1ace6cc5d0ae2c0..680471d1f28a4300700883489c3b8b78335c07da 100644 (file)
@@ -38,8 +38,21 @@ struct svc_stat {
                                rpcbadclnt;
 };
 
-void                   rpc_proc_init(void);
-void                   rpc_proc_exit(void);
+struct net;
+#ifdef CONFIG_PROC_FS
+int                    rpc_proc_init(struct net *);
+void                   rpc_proc_exit(struct net *);
+#else
+static inline int rpc_proc_init(struct net *net)
+{
+       return 0;
+}
+
+static inline void rpc_proc_exit(struct net *net)
+{
+}
+#endif
+
 #ifdef MODULE
 void                   rpc_modcount(struct inode *, int);
 #endif
@@ -54,9 +67,6 @@ void                  svc_proc_unregister(const char *);
 
 void                   svc_seq_show(struct seq_file *,
                                     const struct svc_stat *);
-
-extern struct proc_dir_entry   *proc_net_rpc;
-
 #else
 
 static inline struct proc_dir_entry *rpc_proc_register(struct rpc_stat *s) { return NULL; }
@@ -69,9 +79,6 @@ static inline void svc_proc_unregister(const char *p) {}
 
 static inline void svc_seq_show(struct seq_file *seq,
                                const struct svc_stat *st) {}
-
-#define proc_net_rpc NULL
-
 #endif
 
 #endif /* _LINUX_SUNRPC_STATS_H */
index e84e7ddeecd409554f71dbdaa95f028582ca3928..e20968aac68a11d566a77ced2392edc2e0e4986f 100644 (file)
@@ -34,7 +34,7 @@
 #include <linux/sunrpc/cache.h>
 #include <linux/sunrpc/stats.h>
 #include <linux/sunrpc/rpc_pipe_fs.h>
-#include <net/net_namespace.h>
+#include "netns.h"
 
 #define         RPCDBG_FACILITY RPCDBG_CACHE
 
@@ -1540,6 +1540,8 @@ static const struct file_operations cache_flush_operations_procfs = {
 
 static void remove_cache_proc_entries(struct cache_detail *cd, struct net *net)
 {
+       struct sunrpc_net *sn;
+
        if (cd->u.procfs.proc_ent == NULL)
                return;
        if (cd->u.procfs.flush_ent)
@@ -1549,15 +1551,18 @@ static void remove_cache_proc_entries(struct cache_detail *cd, struct net *net)
        if (cd->u.procfs.content_ent)
                remove_proc_entry("content", cd->u.procfs.proc_ent);
        cd->u.procfs.proc_ent = NULL;
-       remove_proc_entry(cd->name, proc_net_rpc);
+       sn = net_generic(net, sunrpc_net_id);
+       remove_proc_entry(cd->name, sn->proc_net_rpc);
 }
 
 #ifdef CONFIG_PROC_FS
 static int create_cache_proc_entries(struct cache_detail *cd, struct net *net)
 {
        struct proc_dir_entry *p;
+       struct sunrpc_net *sn;
 
-       cd->u.procfs.proc_ent = proc_mkdir(cd->name, proc_net_rpc);
+       sn = net_generic(net, sunrpc_net_id);
+       cd->u.procfs.proc_ent = proc_mkdir(cd->name, sn->proc_net_rpc);
        if (cd->u.procfs.proc_ent == NULL)
                goto out_nomem;
        cd->u.procfs.channel_ent = NULL;
index b2d18af2815ec0ed40ca1dd6e56e133d4cb8ea44..e52ce897dde5da5b93b3615eae9372a1a6fca2d0 100644 (file)
@@ -5,6 +5,7 @@
 #include <net/netns/generic.h>
 
 struct sunrpc_net {
+       struct proc_dir_entry *proc_net_rpc;
 };
 
 extern int sunrpc_net_id;
index ea1046f3f9a3cac31616499559b82aa2930effba..f71a73107ae94adeae35303f95f0b3409aee9e07 100644 (file)
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/svcsock.h>
 #include <linux/sunrpc/metrics.h>
-#include <net/net_namespace.h>
 
-#define RPCDBG_FACILITY        RPCDBG_MISC
+#include "netns.h"
 
-struct proc_dir_entry  *proc_net_rpc = NULL;
+#define RPCDBG_FACILITY        RPCDBG_MISC
 
 /*
  * Get RPC client stats
@@ -218,10 +217,11 @@ EXPORT_SYMBOL_GPL(rpc_print_iostats);
 static inline struct proc_dir_entry *
 do_register(const char *name, void *data, const struct file_operations *fops)
 {
-       rpc_proc_init();
-       dprintk("RPC:       registering /proc/net/rpc/%s\n", name);
+       struct sunrpc_net *sn;
 
-       return proc_create_data(name, 0, proc_net_rpc, fops, data);
+       dprintk("RPC:       registering /proc/net/rpc/%s\n", name);
+       sn = net_generic(&init_net, sunrpc_net_id);
+       return proc_create_data(name, 0, sn->proc_net_rpc, fops, data);
 }
 
 struct proc_dir_entry *
@@ -234,7 +234,10 @@ EXPORT_SYMBOL_GPL(rpc_proc_register);
 void
 rpc_proc_unregister(const char *name)
 {
-       remove_proc_entry(name, proc_net_rpc);
+       struct sunrpc_net *sn;
+
+       sn = net_generic(&init_net, sunrpc_net_id);
+       remove_proc_entry(name, sn->proc_net_rpc);
 }
 EXPORT_SYMBOL_GPL(rpc_proc_unregister);
 
@@ -248,25 +251,29 @@ EXPORT_SYMBOL_GPL(svc_proc_register);
 void
 svc_proc_unregister(const char *name)
 {
-       remove_proc_entry(name, proc_net_rpc);
+       struct sunrpc_net *sn;
+
+       sn = net_generic(&init_net, sunrpc_net_id);
+       remove_proc_entry(name, sn->proc_net_rpc);
 }
 EXPORT_SYMBOL_GPL(svc_proc_unregister);
 
-void
-rpc_proc_init(void)
+int rpc_proc_init(struct net *net)
 {
+       struct sunrpc_net *sn;
+
        dprintk("RPC:       registering /proc/net/rpc\n");
-       if (!proc_net_rpc)
-               proc_net_rpc = proc_mkdir("rpc", init_net.proc_net);
+       sn = net_generic(net, sunrpc_net_id);
+       sn->proc_net_rpc = proc_mkdir("rpc", net->proc_net);
+       if (sn->proc_net_rpc == NULL)
+               return -ENOMEM;
+
+       return 0;
 }
 
-void
-rpc_proc_exit(void)
+void rpc_proc_exit(struct net *net)
 {
        dprintk("RPC:       unregistering /proc/net/rpc\n");
-       if (proc_net_rpc) {
-               proc_net_rpc = NULL;
-               remove_proc_entry("rpc", init_net.proc_net);
-       }
+       remove_proc_entry("rpc", net->proc_net);
 }
 
index faa23229bd25a31c380b8f3eaa5c8c632cedb505..c076af8535db12a987c932be5f4282517aa08b62 100644 (file)
@@ -28,11 +28,21 @@ int sunrpc_net_id;
 
 static __net_init int sunrpc_init_net(struct net *net)
 {
+       int err;
+
+       err = rpc_proc_init(net);
+       if (err)
+               goto err_proc;
+
        return 0;
+
+err_proc:
+       return err;
 }
 
 static __net_exit void sunrpc_exit_net(struct net *net)
 {
+       rpc_proc_exit(net);
 }
 
 static struct pernet_operations sunrpc_net_ops = {
@@ -66,9 +76,6 @@ init_sunrpc(void)
                goto out4;
 #ifdef RPC_DEBUG
        rpc_register_sysctl();
-#endif
-#ifdef CONFIG_PROC_FS
-       rpc_proc_init();
 #endif
        cache_register(&ip_map_cache);
        cache_register(&unix_gid_cache);
@@ -100,9 +107,6 @@ cleanup_sunrpc(void)
        unregister_pernet_subsys(&sunrpc_net_ops);
 #ifdef RPC_DEBUG
        rpc_unregister_sysctl();
-#endif
-#ifdef CONFIG_PROC_FS
-       rpc_proc_exit();
 #endif
        rcu_barrier(); /* Wait for completion of call_rcu()'s */
 }