NFS: handle NFS caches dentries by network namespace aware routines
authorStanislav Kinsbursky <skinsbursky@parallels.com>
Fri, 25 Nov 2011 14:12:56 +0000 (17:12 +0300)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Tue, 31 Jan 2012 23:20:26 +0000 (18:20 -0500)
This patch makes NFS caches PipeFS dentries allocated and destroyed in network
namespace context by PipeFS network namespace aware routines.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
fs/nfs/cache_lib.c
fs/nfs/cache_lib.h
fs/nfs/dns_resolve.c

index 9d79a2eaab276a0159b06cc67fd0dba078ef782b..5dd017bbb7a270fc8af09ca81b5e228f93b9fff0 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/slab.h>
 #include <linux/sunrpc/cache.h>
 #include <linux/sunrpc/rpc_pipe_fs.h>
+#include <net/net_namespace.h>
 
 #include "cache_lib.h"
 
@@ -111,20 +112,34 @@ int nfs_cache_wait_for_upcall(struct nfs_cache_defer_req *dreq)
        return 0;
 }
 
-int nfs_cache_register(struct cache_detail *cd)
+static int nfs_cache_register_sb(struct super_block *sb, struct cache_detail *cd)
+{
+       int ret;
+       struct dentry *dir;
+
+       dir = rpc_d_lookup_sb(sb, "cache");
+       BUG_ON(dir == NULL);
+       ret = sunrpc_cache_register_pipefs(dir, cd->name, 0600, cd);
+       dput(dir);
+       return ret;
+}
+
+int nfs_cache_register_net(struct net *net, struct cache_detail *cd)
 {
        struct vfsmount *mnt;
-       struct path path;
+       struct super_block *pipefs_sb;
        int ret;
 
        mnt = rpc_get_mount();
        if (IS_ERR(mnt))
                return PTR_ERR(mnt);
-       ret = vfs_path_lookup(mnt->mnt_root, mnt, "/cache", 0, &path);
-       if (ret)
+       pipefs_sb = rpc_get_sb_net(net);
+       if (!pipefs_sb) {
+               ret = -ENOENT;
                goto err;
-       ret = sunrpc_cache_register_pipefs(path.dentry, cd->name, 0600, cd);
-       path_put(&path);
+       }
+       ret = nfs_cache_register_sb(pipefs_sb, cd);
+       rpc_put_sb_net(net);
        if (!ret)
                return ret;
 err:
@@ -132,10 +147,21 @@ err:
        return ret;
 }
 
-void nfs_cache_unregister(struct cache_detail *cd)
+static void nfs_cache_unregister_sb(struct super_block *sb, struct cache_detail *cd)
 {
-       sunrpc_cache_unregister_pipefs(cd);
-       sunrpc_destroy_cache_detail(cd);
+       if (cd->u.pipefs.dir)
+               sunrpc_cache_unregister_pipefs(cd);
+}
+
+void nfs_cache_unregister_net(struct net *net, struct cache_detail *cd)
+{
+       struct super_block *pipefs_sb;
+
+       pipefs_sb = rpc_get_sb_net(net);
+       if (pipefs_sb) {
+               nfs_cache_unregister_sb(pipefs_sb, cd);
+               rpc_put_sb_net(net);
+       }
        rpc_put_mount();
 }
 
index 815dd6651c9f9b144ffa6d509775dcec48c32ec6..e0a6cc4b01b9bad72bc46e3986d0b3473ba355c9 100644 (file)
@@ -25,5 +25,5 @@ extern int nfs_cache_wait_for_upcall(struct nfs_cache_defer_req *dreq);
 
 extern void nfs_cache_init(struct cache_detail *cd);
 extern void nfs_cache_destroy(struct cache_detail *cd);
-extern int nfs_cache_register(struct cache_detail *cd);
-extern void nfs_cache_unregister(struct cache_detail *cd);
+extern int nfs_cache_register_net(struct net *net, struct cache_detail *cd);
+extern void nfs_cache_unregister_net(struct net *net, struct cache_detail *cd);
index 619dea6b5ccf9874fc73664bfd2d1abe9b95f75d..3cbf4b88f8276facea63181bc404f155ab5fbf81 100644 (file)
@@ -364,7 +364,7 @@ int nfs_dns_resolver_init(void)
        int err;
 
        nfs_cache_init(&nfs_dns_resolve);
-       err = nfs_cache_register(&nfs_dns_resolve);
+       err = nfs_cache_register_net(&init_net, &nfs_dns_resolve);
        if (err) {
                nfs_cache_destroy(&nfs_dns_resolve);
                return err;
@@ -374,7 +374,7 @@ int nfs_dns_resolver_init(void)
 
 void nfs_dns_resolver_destroy(void)
 {
-       nfs_cache_unregister(&nfs_dns_resolve);
+       nfs_cache_unregister_net(&init_net, &nfs_dns_resolve);
        nfs_cache_destroy(&nfs_dns_resolve);
 }