diff options
author | Stanislav Kinsbursky <skinsbursky@parallels.com> | 2012-04-11 07:13:21 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2012-04-12 09:11:11 -0400 |
commit | b3853e0ea1f2ef58f7e7c03e47819e2ae3766dea (patch) | |
tree | e1d54f74e25a7878c2d786d120cd1a97f240ac18 /fs | |
parent | 2a75cfa64e63502e54e40f99ba07411544bd3190 (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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfsd/export.c | 47 | ||||
-rw-r--r-- | fs/nfsd/netns.h | 2 | ||||
-rw-r--r-- | fs/nfsd/nfsctl.c | 2 | ||||
-rw-r--r-- | fs/nfsd/nfssvc.c | 2 |
4 files changed, 36 insertions, 17 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 | ||
301 | static struct cache_head *export_table[EXPORT_HASHMAX]; | ||
302 | |||
303 | static void nfsd4_fslocs_free(struct nfsd4_fs_locations *fsloc) | 303 | static 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 | ||
711 | struct cache_detail svc_export_cache = { | 711 | struct 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 | */ |
837 | int | 836 | int |
838 | exp_rootfh(svc_client *clp, char *name, | 837 | exp_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 * | |||
930 | rqst_exp_get_by_name(struct svc_rqst *rqstp, struct path *path) | 930 | rqst_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 * | |||
960 | rqst_exp_find(struct svc_rqst *rqstp, int fsid_type, u32 *fsidv) | 961 | rqst_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 | |||
1238 | nfsd_export_init(struct net *net) | 1240 | nfsd_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 | ||
1259 | unregister_export_cache: | ||
1260 | cache_unregister_net(nn->svc_export_cache, net); | ||
1261 | destroy_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 | */ |
1256 | void | 1269 | void |
1257 | nfsd_export_flush(void) | 1270 | nfsd_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) | |||
1266 | void | 1281 | void |
1267 | nfsd_export_shutdown(struct net *net) | 1282 | nfsd_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 | ||
29 | struct nfsd_net { | 29 | struct 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 | ||
33 | extern int nfsd_net_id; | 35 | extern 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 | ||
267 | void nfsd_reset_versions(void) | 267 | void nfsd_reset_versions(void) |