Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Stanislav Kinsbursky and committed by
J. Bruce Fields
b3853e0e 2a75cfa6

+38 -19
+32 -15
fs/nfsd/export.c
··· 15 15 #include <linux/namei.h> 16 16 #include <linux/module.h> 17 17 #include <linux/exportfs.h> 18 + #include <linux/sunrpc/svc_xprt.h> 18 19 19 20 #include <net/ipv6.h> 20 21 21 22 #include "nfsd.h" 22 23 #include "nfsfh.h" 24 + #include "netns.h" 23 25 24 26 #define NFSDDBG_FACILITY NFSDDBG_EXPORT 25 27 ··· 299 297 300 298 #define EXPORT_HASHBITS 8 301 299 #define EXPORT_HASHMAX (1<< EXPORT_HASHBITS) 302 - 303 - static struct cache_head *export_table[EXPORT_HASHMAX]; 304 300 305 301 static void nfsd4_fslocs_free(struct nfsd4_fs_locations *fsloc) 306 302 { ··· 708 708 return NULL; 709 709 } 710 710 711 - struct cache_detail svc_export_cache = { 711 + struct cache_detail svc_export_cache_template = { 712 712 .owner = THIS_MODULE, 713 713 .hash_size = EXPORT_HASHMAX, 714 - .hash_table = export_table, 715 714 .name = "nfsd.export", 716 715 .cache_put = svc_export_put, 717 716 .cache_upcall = svc_export_upcall, ··· 834 835 * since its harder to fool a kernel module than a user space program. 835 836 */ 836 837 int 837 - exp_rootfh(svc_client *clp, char *name, 838 + exp_rootfh(struct net *net, svc_client *clp, char *name, 838 839 struct knfsd_fh *f, int maxsize) 839 840 { 840 841 struct svc_export *exp; ··· 842 843 struct inode *inode; 843 844 struct svc_fh fh; 844 845 int err; 845 - struct cache_detail *cd = &svc_export_cache; 846 + struct nfsd_net *nn = net_generic(net, nfsd_net_id); 847 + struct cache_detail *cd = nn->svc_export_cache; 846 848 847 849 err = -EPERM; 848 850 /* NB: we probably ought to check that it's NUL-terminated */ ··· 930 930 rqst_exp_get_by_name(struct svc_rqst *rqstp, struct path *path) 931 931 { 932 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 936 if (rqstp->rq_client == NULL) 936 937 goto gss; ··· 961 960 rqst_exp_find(struct svc_rqst *rqstp, int fsid_type, u32 *fsidv) 962 961 { 963 962 struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT); 964 - struct cache_detail *cd = &svc_export_cache; 963 + struct nfsd_net *nn = net_generic(rqstp->rq_xprt->xpt_net, nfsd_net_id); 964 + struct cache_detail *cd = nn->svc_export_cache; 965 965 966 966 if (rqstp->rq_client == NULL) 967 967 goto gss; ··· 1240 1238 nfsd_export_init(struct net *net) 1241 1239 { 1242 1240 int rv; 1241 + struct nfsd_net *nn = net_generic(net, nfsd_net_id); 1242 + 1243 1243 dprintk("nfsd: initializing export module (net: %p).\n", net); 1244 1244 1245 - rv = cache_register_net(&svc_export_cache, net); 1245 + nn->svc_export_cache = cache_create_net(&svc_export_cache_template, net); 1246 + if (IS_ERR(nn->svc_export_cache)) 1247 + return PTR_ERR(nn->svc_export_cache); 1248 + rv = cache_register_net(nn->svc_export_cache, net); 1246 1249 if (rv) 1247 - return rv; 1250 + goto destroy_export_cache; 1251 + 1248 1252 rv = cache_register_net(&svc_expkey_cache, net); 1249 1253 if (rv) 1250 - cache_unregister_net(&svc_export_cache, net); 1251 - return rv; 1254 + goto unregister_export_cache; 1255 + return 0; 1252 1256 1257 + unregister_export_cache: 1258 + cache_unregister_net(nn->svc_export_cache, net); 1259 + destroy_export_cache: 1260 + cache_destroy_net(nn->svc_export_cache, net); 1261 + return rv; 1253 1262 } 1254 1263 1255 1264 /* 1256 1265 * Flush exports table - called when last nfsd thread is killed 1257 1266 */ 1258 1267 void 1259 - nfsd_export_flush(void) 1268 + nfsd_export_flush(struct net *net) 1260 1269 { 1270 + struct nfsd_net *nn = net_generic(net, nfsd_net_id); 1271 + 1261 1272 cache_purge(&svc_expkey_cache); 1262 - cache_purge(&svc_export_cache); 1273 + cache_purge(nn->svc_export_cache); 1263 1274 } 1264 1275 1265 1276 /* ··· 1281 1266 void 1282 1267 nfsd_export_shutdown(struct net *net) 1283 1268 { 1269 + struct nfsd_net *nn = net_generic(net, nfsd_net_id); 1284 1270 1285 1271 dprintk("nfsd: shutting down export module (net: %p).\n", net); 1286 1272 1287 1273 cache_unregister_net(&svc_expkey_cache, net); 1288 - cache_unregister_net(&svc_export_cache, net); 1274 + cache_unregister_net(nn->svc_export_cache, net); 1275 + cache_destroy_net(nn->svc_export_cache, net); 1289 1276 svcauth_unix_purge(); 1290 1277 1291 1278 dprintk("nfsd: export shutdown complete (net: %p).\n", net);
+2
fs/nfsd/netns.h
··· 28 28 29 29 struct nfsd_net { 30 30 struct cld_net *cld_net; 31 + 32 + struct cache_detail *svc_export_cache; 31 33 }; 32 34 33 35 extern int nfsd_net_id;
+1 -1
fs/nfsd/nfsctl.c
··· 354 354 if (!dom) 355 355 return -ENOMEM; 356 356 357 - len = exp_rootfh(dom, path, &fh, maxsize); 357 + len = exp_rootfh(&init_net, dom, path, &fh, maxsize); 358 358 auth_domain_put(dom); 359 359 if (len) 360 360 return len;
+1 -1
fs/nfsd/nfssvc.c
··· 261 261 262 262 printk(KERN_WARNING "nfsd: last server has exited, flushing export " 263 263 "cache\n"); 264 - nfsd_export_flush(); 264 + nfsd_export_flush(net); 265 265 } 266 266 267 267 void nfsd_reset_versions(void)
+2 -2
include/linux/nfsd/export.h
··· 132 132 */ 133 133 int nfsd_export_init(struct net *); 134 134 void nfsd_export_shutdown(struct net *); 135 - void nfsd_export_flush(void); 135 + void nfsd_export_flush(struct net *); 136 136 struct svc_export * rqst_exp_get_by_name(struct svc_rqst *, 137 137 struct path *); 138 138 struct svc_export * rqst_exp_parent(struct svc_rqst *, 139 139 struct path *); 140 140 struct svc_export * rqst_find_fsidzero_export(struct svc_rqst *); 141 - int exp_rootfh(struct auth_domain *, 141 + int exp_rootfh(struct net *, struct auth_domain *, 142 142 char *path, struct knfsd_fh *, int maxsize); 143 143 __be32 exp_pseudoroot(struct svc_rqst *, struct svc_fh *); 144 144 __be32 nfserrno(int errno);