Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5c1cacb1 authored by Stanislav Kinsbursky's avatar Stanislav Kinsbursky Committed by Trond Myklebust
Browse files

NFS: handle NFS caches dentries by network namespace aware routines



This patch makes NFS caches PipeFS dentries allocated and destroyed in network
namespace context by PipeFS network namespace aware routines.

Signed-off-by: default avatarStanislav Kinsbursky <skinsbursky@parallels.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 9222b955
Loading
Loading
Loading
Loading
+35 −9
Original line number Diff line number Diff line
@@ -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 @@ int nfs_cache_register(struct cache_detail *cd)
	return ret;
}

void nfs_cache_unregister(struct cache_detail *cd)
static void nfs_cache_unregister_sb(struct super_block *sb, struct cache_detail *cd)
{
	if (cd->u.pipefs.dir)
		sunrpc_cache_unregister_pipefs(cd);
	sunrpc_destroy_cache_detail(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();
}

+2 −2
Original line number Diff line number Diff line
@@ -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);
+2 −2
Original line number Diff line number Diff line
@@ -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);
}