aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStanislav Kinsbursky <skinsbursky@parallels.com>2012-04-11 07:13:21 -0400
committerJ. Bruce Fields <bfields@redhat.com>2012-04-12 09:11:11 -0400
commitb3853e0ea1f2ef58f7e7c03e47819e2ae3766dea (patch)
treee1d54f74e25a7878c2d786d120cd1a97f240ac18
parent2a75cfa64e63502e54e40f99ba07411544bd3190 (diff)
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: Stanislav Kinsbursky <skinsbursky@parallels.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r--fs/nfsd/export.c47
-rw-r--r--fs/nfsd/netns.h2
-rw-r--r--fs/nfsd/nfsctl.c2
-rw-r--r--fs/nfsd/nfssvc.c2
-rw-r--r--include/linux/nfsd/export.h4
5 files changed, 38 insertions, 19 deletions
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 688264b55a3a..84d020fc0e37 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -15,11 +15,13 @@
15#include <linux/namei.h> 15#include <linux/namei.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/exportfs.h> 17#include <linux/exportfs.h>
18#include <linux/sunrpc/svc_xprt.h>
18 19
19#include <net/ipv6.h> 20#include <net/ipv6.h>
20 21
21#include "nfsd.h" 22#include "nfsd.h"
22#include "nfsfh.h" 23#include "nfsfh.h"
24#include "netns.h"
23 25
24#define NFSDDBG_FACILITY NFSDDBG_EXPORT 26#define NFSDDBG_FACILITY NFSDDBG_EXPORT
25 27
@@ -298,8 +300,6 @@ svc_expkey_update(struct cache_detail *cd, struct svc_expkey *new,
298#define EXPORT_HASHBITS 8 300#define EXPORT_HASHBITS 8
299#define EXPORT_HASHMAX (1<< EXPORT_HASHBITS) 301#define EXPORT_HASHMAX (1<< EXPORT_HASHBITS)
300 302
301static struct cache_head *export_table[EXPORT_HASHMAX];
302
303static void nfsd4_fslocs_free(struct nfsd4_fs_locations *fsloc) 303static void nfsd4_fslocs_free(struct nfsd4_fs_locations *fsloc)
304{ 304{
305 int i; 305 int i;
@@ -708,10 +708,9 @@ static struct cache_head *svc_export_alloc(void)
708 return NULL; 708 return NULL;
709} 709}
710 710
711struct cache_detail svc_export_cache = { 711struct cache_detail svc_export_cache_template = {
712 .owner = THIS_MODULE, 712 .owner = THIS_MODULE,
713 .hash_size = EXPORT_HASHMAX, 713 .hash_size = EXPORT_HASHMAX,
714 .hash_table = export_table,
715 .name = "nfsd.export", 714 .name = "nfsd.export",
716 .cache_put = svc_export_put, 715 .cache_put = svc_export_put,
717 .cache_upcall = svc_export_upcall, 716 .cache_upcall = svc_export_upcall,
@@ -835,7 +834,7 @@ static struct svc_export *exp_parent(struct cache_detail *cd, svc_client *clp,
835 * since its harder to fool a kernel module than a user space program. 834 * since its harder to fool a kernel module than a user space program.
836 */ 835 */
837int 836int
838exp_rootfh(svc_client *clp, char *name, 837exp_rootfh(struct net *net, svc_client *clp, char *name,
839 struct knfsd_fh *f, int maxsize) 838 struct knfsd_fh *f, int maxsize)
840{ 839{
841 struct svc_export *exp; 840 struct svc_export *exp;
@@ -843,7 +842,8 @@ exp_rootfh(svc_client *clp, char *name,
843 struct inode *inode; 842 struct inode *inode;
844 struct svc_fh fh; 843 struct svc_fh fh;
845 int err; 844 int err;
846 struct cache_detail *cd = &svc_export_cache; 845 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
846 struct cache_detail *cd = nn->svc_export_cache;
847 847
848 err = -EPERM; 848 err = -EPERM;
849 /* NB: we probably ought to check that it's NUL-terminated */ 849 /* NB: we probably ought to check that it's NUL-terminated */
@@ -930,7 +930,8 @@ struct svc_export *
930rqst_exp_get_by_name(struct svc_rqst *rqstp, struct path *path) 930rqst_exp_get_by_name(struct svc_rqst *rqstp, struct path *path)
931{ 931{
932 struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT); 932 struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT);
933 struct cache_detail *cd = &svc_export_cache; 933 struct nfsd_net *nn = net_generic(rqstp->rq_xprt->xpt_net, nfsd_net_id);
934 struct cache_detail *cd = nn->svc_export_cache;
934 935
935 if (rqstp->rq_client == NULL) 936 if (rqstp->rq_client == NULL)
936 goto gss; 937 goto gss;
@@ -960,7 +961,8 @@ struct svc_export *
960rqst_exp_find(struct svc_rqst *rqstp, int fsid_type, u32 *fsidv) 961rqst_exp_find(struct svc_rqst *rqstp, int fsid_type, u32 *fsidv)
961{ 962{
962 struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT); 963 struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT);
963 struct cache_detail *cd = &svc_export_cache; 964 struct nfsd_net *nn = net_generic(rqstp->rq_xprt->xpt_net, nfsd_net_id);
965 struct cache_detail *cd = nn->svc_export_cache;
964 966
965 if (rqstp->rq_client == NULL) 967 if (rqstp->rq_client == NULL)
966 goto gss; 968 goto gss;
@@ -1238,26 +1240,39 @@ int
1238nfsd_export_init(struct net *net) 1240nfsd_export_init(struct net *net)
1239{ 1241{
1240 int rv; 1242 int rv;
1243 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1244
1241 dprintk("nfsd: initializing export module (net: %p).\n", net); 1245 dprintk("nfsd: initializing export module (net: %p).\n", net);
1242 1246
1243 rv = cache_register_net(&svc_export_cache, net); 1247 nn->svc_export_cache = cache_create_net(&svc_export_cache_template, net);
1248 if (IS_ERR(nn->svc_export_cache))
1249 return PTR_ERR(nn->svc_export_cache);
1250 rv = cache_register_net(nn->svc_export_cache, net);
1244 if (rv) 1251 if (rv)
1245 return rv; 1252 goto destroy_export_cache;
1253
1246 rv = cache_register_net(&svc_expkey_cache, net); 1254 rv = cache_register_net(&svc_expkey_cache, net);
1247 if (rv) 1255 if (rv)
1248 cache_unregister_net(&svc_export_cache, net); 1256 goto unregister_export_cache;
1249 return rv; 1257 return 0;
1250 1258
1259unregister_export_cache:
1260 cache_unregister_net(nn->svc_export_cache, net);
1261destroy_export_cache:
1262 cache_destroy_net(nn->svc_export_cache, net);
1263 return rv;
1251} 1264}
1252 1265
1253/* 1266/*
1254 * Flush exports table - called when last nfsd thread is killed 1267 * Flush exports table - called when last nfsd thread is killed
1255 */ 1268 */
1256void 1269void
1257nfsd_export_flush(void) 1270nfsd_export_flush(struct net *net)
1258{ 1271{
1272 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1273
1259 cache_purge(&svc_expkey_cache); 1274 cache_purge(&svc_expkey_cache);
1260 cache_purge(&svc_export_cache); 1275 cache_purge(nn->svc_export_cache);
1261} 1276}
1262 1277
1263/* 1278/*
@@ -1266,11 +1281,13 @@ nfsd_export_flush(void)
1266void 1281void
1267nfsd_export_shutdown(struct net *net) 1282nfsd_export_shutdown(struct net *net)
1268{ 1283{
1284 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1269 1285
1270 dprintk("nfsd: shutting down export module (net: %p).\n", net); 1286 dprintk("nfsd: shutting down export module (net: %p).\n", net);
1271 1287
1272 cache_unregister_net(&svc_expkey_cache, net); 1288 cache_unregister_net(&svc_expkey_cache, net);
1273 cache_unregister_net(&svc_export_cache, net); 1289 cache_unregister_net(nn->svc_export_cache, net);
1290 cache_destroy_net(nn->svc_export_cache, net);
1274 svcauth_unix_purge(); 1291 svcauth_unix_purge();
1275 1292
1276 dprintk("nfsd: export shutdown complete (net: %p).\n", net); 1293 dprintk("nfsd: export shutdown complete (net: %p).\n", net);
diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h
index 12e0cff435b4..c1c6242942a9 100644
--- a/fs/nfsd/netns.h
+++ b/fs/nfsd/netns.h
@@ -28,6 +28,8 @@ struct cld_net;
28 28
29struct nfsd_net { 29struct nfsd_net {
30 struct cld_net *cld_net; 30 struct cld_net *cld_net;
31
32 struct cache_detail *svc_export_cache;
31}; 33};
32 34
33extern int nfsd_net_id; 35extern int nfsd_net_id;
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index bc76f8ebbe5e..ddb9f8787379 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -354,7 +354,7 @@ static ssize_t write_filehandle(struct file *file, char *buf, size_t size)
354 if (!dom) 354 if (!dom)
355 return -ENOMEM; 355 return -ENOMEM;
356 356
357 len = exp_rootfh(dom, path, &fh, maxsize); 357 len = exp_rootfh(&init_net, dom, path, &fh, maxsize);
358 auth_domain_put(dom); 358 auth_domain_put(dom);
359 if (len) 359 if (len)
360 return len; 360 return len;
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 78e521392df1..cb4d51d8cbdb 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -261,7 +261,7 @@ static void nfsd_last_thread(struct svc_serv *serv, struct net *net)
261 261
262 printk(KERN_WARNING "nfsd: last server has exited, flushing export " 262 printk(KERN_WARNING "nfsd: last server has exited, flushing export "
263 "cache\n"); 263 "cache\n");
264 nfsd_export_flush(); 264 nfsd_export_flush(net);
265} 265}
266 266
267void nfsd_reset_versions(void) 267void nfsd_reset_versions(void)
diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h
index 375096c083d3..565c2122993f 100644
--- a/include/linux/nfsd/export.h
+++ b/include/linux/nfsd/export.h
@@ -132,13 +132,13 @@ __be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp);
132 */ 132 */
133int nfsd_export_init(struct net *); 133int nfsd_export_init(struct net *);
134void nfsd_export_shutdown(struct net *); 134void nfsd_export_shutdown(struct net *);
135void nfsd_export_flush(void); 135void nfsd_export_flush(struct net *);
136struct svc_export * rqst_exp_get_by_name(struct svc_rqst *, 136struct svc_export * rqst_exp_get_by_name(struct svc_rqst *,
137 struct path *); 137 struct path *);
138struct svc_export * rqst_exp_parent(struct svc_rqst *, 138struct svc_export * rqst_exp_parent(struct svc_rqst *,
139 struct path *); 139 struct path *);
140struct svc_export * rqst_find_fsidzero_export(struct svc_rqst *); 140struct svc_export * rqst_find_fsidzero_export(struct svc_rqst *);
141int exp_rootfh(struct auth_domain *, 141int exp_rootfh(struct net *, struct auth_domain *,
142 char *path, struct knfsd_fh *, int maxsize); 142 char *path, struct knfsd_fh *, int maxsize);
143__be32 exp_pseudoroot(struct svc_rqst *, struct svc_fh *); 143__be32 exp_pseudoroot(struct svc_rqst *, struct svc_fh *);
144__be32 nfserrno(int errno); 144__be32 nfserrno(int errno);