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

Commit b3853e0e authored by Stanislav Kinsbursky's avatar Stanislav Kinsbursky Committed by J. Bruce Fields
Browse files

nfsd: make export cache allocated per network namespace context



This patch also changes prototypes of nfsd_export_flush() and exp_rootfh():
network namespace parameter added.

Signed-off-by: default avatarStanislav Kinsbursky <skinsbursky@parallels.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 2a75cfa6
Loading
Loading
Loading
Loading
+32 −15
Original line number Diff line number Diff line
@@ -15,11 +15,13 @@
#include <linux/namei.h>
#include <linux/module.h>
#include <linux/exportfs.h>
#include <linux/sunrpc/svc_xprt.h>

#include <net/ipv6.h>

#include "nfsd.h"
#include "nfsfh.h"
#include "netns.h"

#define NFSDDBG_FACILITY	NFSDDBG_EXPORT

@@ -298,8 +300,6 @@ svc_expkey_update(struct cache_detail *cd, struct svc_expkey *new,
#define	EXPORT_HASHBITS		8
#define	EXPORT_HASHMAX		(1<< EXPORT_HASHBITS)

static struct cache_head *export_table[EXPORT_HASHMAX];

static void nfsd4_fslocs_free(struct nfsd4_fs_locations *fsloc)
{
	int i;
@@ -708,10 +708,9 @@ static struct cache_head *svc_export_alloc(void)
		return NULL;
}

struct cache_detail svc_export_cache = {
struct cache_detail svc_export_cache_template = {
	.owner		= THIS_MODULE,
	.hash_size	= EXPORT_HASHMAX,
	.hash_table	= export_table,
	.name		= "nfsd.export",
	.cache_put	= svc_export_put,
	.cache_upcall	= svc_export_upcall,
@@ -835,7 +834,7 @@ static struct svc_export *exp_parent(struct cache_detail *cd, svc_client *clp,
 * since its harder to fool a kernel module than a user space program.
 */
int
exp_rootfh(svc_client *clp, char *name,
exp_rootfh(struct net *net, svc_client *clp, char *name,
	   struct knfsd_fh *f, int maxsize)
{
	struct svc_export	*exp;
@@ -843,7 +842,8 @@ exp_rootfh(svc_client *clp, char *name,
	struct inode		*inode;
	struct svc_fh		fh;
	int			err;
	struct cache_detail	*cd = &svc_export_cache;
	struct nfsd_net		*nn = net_generic(net, nfsd_net_id);
	struct cache_detail	*cd = nn->svc_export_cache;

	err = -EPERM;
	/* NB: we probably ought to check that it's NUL-terminated */
@@ -930,7 +930,8 @@ struct svc_export *
rqst_exp_get_by_name(struct svc_rqst *rqstp, struct path *path)
{
	struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT);
	struct cache_detail *cd = &svc_export_cache;
	struct nfsd_net *nn = net_generic(rqstp->rq_xprt->xpt_net, nfsd_net_id);
	struct cache_detail *cd = nn->svc_export_cache;

	if (rqstp->rq_client == NULL)
		goto gss;
@@ -960,7 +961,8 @@ struct svc_export *
rqst_exp_find(struct svc_rqst *rqstp, int fsid_type, u32 *fsidv)
{
	struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT);
	struct cache_detail *cd = &svc_export_cache;
	struct nfsd_net *nn = net_generic(rqstp->rq_xprt->xpt_net, nfsd_net_id);
	struct cache_detail *cd = nn->svc_export_cache;

	if (rqstp->rq_client == NULL)
		goto gss;
@@ -1238,26 +1240,39 @@ int
nfsd_export_init(struct net *net)
{
	int rv;
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);

	dprintk("nfsd: initializing export module (net: %p).\n", net);

	rv = cache_register_net(&svc_export_cache, net);
	nn->svc_export_cache = cache_create_net(&svc_export_cache_template, net);
	if (IS_ERR(nn->svc_export_cache))
		return PTR_ERR(nn->svc_export_cache);
	rv = cache_register_net(nn->svc_export_cache, net);
	if (rv)
		return rv;
		goto destroy_export_cache;

	rv = cache_register_net(&svc_expkey_cache, net);
	if (rv)
		cache_unregister_net(&svc_export_cache, net);
	return rv;
		goto unregister_export_cache;
	return 0;

unregister_export_cache:
	cache_unregister_net(nn->svc_export_cache, net);
destroy_export_cache:
	cache_destroy_net(nn->svc_export_cache, net);
	return rv;
}

/*
 * Flush exports table - called when last nfsd thread is killed
 */
void
nfsd_export_flush(void)
nfsd_export_flush(struct net *net)
{
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);

	cache_purge(&svc_expkey_cache);
	cache_purge(&svc_export_cache);
	cache_purge(nn->svc_export_cache);
}

/*
@@ -1266,11 +1281,13 @@ nfsd_export_flush(void)
void
nfsd_export_shutdown(struct net *net)
{
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);

	dprintk("nfsd: shutting down export module (net: %p).\n", net);

	cache_unregister_net(&svc_expkey_cache, net);
	cache_unregister_net(&svc_export_cache, net);
	cache_unregister_net(nn->svc_export_cache, net);
	cache_destroy_net(nn->svc_export_cache, net);
	svcauth_unix_purge();

	dprintk("nfsd: export shutdown complete (net: %p).\n", net);
+2 −0
Original line number Diff line number Diff line
@@ -28,6 +28,8 @@ struct cld_net;

struct nfsd_net {
	struct cld_net *cld_net;

	struct cache_detail *svc_export_cache;
};

extern int nfsd_net_id;
+1 −1
Original line number Diff line number Diff line
@@ -354,7 +354,7 @@ static ssize_t write_filehandle(struct file *file, char *buf, size_t size)
	if (!dom)
		return -ENOMEM;

	len = exp_rootfh(dom, path, &fh,  maxsize);
	len = exp_rootfh(&init_net, dom, path, &fh,  maxsize);
	auth_domain_put(dom);
	if (len)
		return len;
+1 −1
Original line number Diff line number Diff line
@@ -261,7 +261,7 @@ static void nfsd_last_thread(struct svc_serv *serv, struct net *net)

	printk(KERN_WARNING "nfsd: last server has exited, flushing export "
			    "cache\n");
	nfsd_export_flush();
	nfsd_export_flush(net);
}

void nfsd_reset_versions(void)
+2 −2
Original line number Diff line number Diff line
@@ -132,13 +132,13 @@ __be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp);
 */
int			nfsd_export_init(struct net *);
void			nfsd_export_shutdown(struct net *);
void			nfsd_export_flush(void);
void			nfsd_export_flush(struct net *);
struct svc_export *	rqst_exp_get_by_name(struct svc_rqst *,
					     struct path *);
struct svc_export *	rqst_exp_parent(struct svc_rqst *,
					struct path *);
struct svc_export *	rqst_find_fsidzero_export(struct svc_rqst *);
int			exp_rootfh(struct auth_domain *, 
int			exp_rootfh(struct net *, struct auth_domain *,
					char *path, struct knfsd_fh *, int maxsize);
__be32			exp_pseudoroot(struct svc_rqst *, struct svc_fh *);
__be32			nfserrno(int errno);