aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@citi.umich.edu>2007-11-08 17:20:34 -0500
committerJ. Bruce Fields <bfields@citi.umich.edu>2008-02-01 16:42:05 -0500
commitdbf847ecb6318d3a22c6758fe39696d00f39063a (patch)
tree2b71e776ca98bc94258f3539bd7f0ea53d2733a8
parentffe9386b6e08e7132cb7730025d0ea310e08a182 (diff)
knfsd: allow cache_register to return error on failure
Newer server features such as nfsv4 and gss depend on proc to work, so a failure to initialize the proc files they need should be treated as fatal. Thanks to Andrew Morton for style fix and compile fix in case where CONFIG_NFSD_V4 is undefined. Cc: Andrew Morton <akpm@linux-foundation.org> Acked-by: NeilBrown <neilb@suse.de> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
-rw-r--r--fs/nfsd/export.c12
-rw-r--r--fs/nfsd/nfs4idmap.c13
-rw-r--r--fs/nfsd/nfsctl.c12
-rw-r--r--include/linux/nfsd/export.h2
-rw-r--r--include/linux/nfsd_idmap.h11
-rw-r--r--include/linux/sunrpc/cache.h2
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c17
-rw-r--r--net/sunrpc/cache.c30
8 files changed, 74 insertions, 25 deletions
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index d29b70a28f2b..cbbc594ef592 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -1637,13 +1637,19 @@ exp_verify_string(char *cp, int max)
1637/* 1637/*
1638 * Initialize the exports module. 1638 * Initialize the exports module.
1639 */ 1639 */
1640void 1640int
1641nfsd_export_init(void) 1641nfsd_export_init(void)
1642{ 1642{
1643 int rv;
1643 dprintk("nfsd: initializing export module.\n"); 1644 dprintk("nfsd: initializing export module.\n");
1644 1645
1645 cache_register(&svc_export_cache); 1646 rv = cache_register(&svc_export_cache);
1646 cache_register(&svc_expkey_cache); 1647 if (rv)
1648 return rv;
1649 rv = cache_register(&svc_expkey_cache);
1650 if (rv)
1651 cache_unregister(&svc_export_cache);
1652 return rv;
1647 1653
1648} 1654}
1649 1655
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c
index ef22179c49ad..996bd88b75ba 100644
--- a/fs/nfsd/nfs4idmap.c
+++ b/fs/nfsd/nfs4idmap.c
@@ -464,11 +464,18 @@ nametoid_update(struct ent *new, struct ent *old)
464 * Exported API 464 * Exported API
465 */ 465 */
466 466
467void 467int
468nfsd_idmap_init(void) 468nfsd_idmap_init(void)
469{ 469{
470 cache_register(&idtoname_cache); 470 int rv;
471 cache_register(&nametoid_cache); 471
472 rv = cache_register(&idtoname_cache);
473 if (rv)
474 return rv;
475 rv = cache_register(&nametoid_cache);
476 if (rv)
477 cache_unregister(&idtoname_cache);
478 return rv;
472} 479}
473 480
474void 481void
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 2b95597aa4a5..4aba92698581 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -707,9 +707,13 @@ static int __init init_nfsd(void)
707 retval = nfsd_reply_cache_init(); 707 retval = nfsd_reply_cache_init();
708 if (retval) 708 if (retval)
709 goto out_free_stat; 709 goto out_free_stat;
710 nfsd_export_init(); /* Exports table */ 710 retval = nfsd_export_init();
711 if (retval)
712 goto out_free_cache;
711 nfsd_lockd_init(); /* lockd->nfsd callbacks */ 713 nfsd_lockd_init(); /* lockd->nfsd callbacks */
712 nfsd_idmap_init(); /* Name to ID mapping */ 714 retval = nfsd_idmap_init();
715 if (retval)
716 goto out_free_lockd;
713 retval = create_proc_exports_entry(); 717 retval = create_proc_exports_entry();
714 if (retval) 718 if (retval)
715 goto out_free_idmap; 719 goto out_free_idmap;
@@ -720,10 +724,12 @@ static int __init init_nfsd(void)
720out_free_all: 724out_free_all:
721 remove_proc_entry("fs/nfs/exports", NULL); 725 remove_proc_entry("fs/nfs/exports", NULL);
722 remove_proc_entry("fs/nfs", NULL); 726 remove_proc_entry("fs/nfs", NULL);
723 nfsd_idmap_shutdown();
724out_free_idmap: 727out_free_idmap:
728 nfsd_idmap_shutdown();
729out_free_lockd:
725 nfsd_lockd_shutdown(); 730 nfsd_lockd_shutdown();
726 nfsd_export_shutdown(); 731 nfsd_export_shutdown();
732out_free_cache:
727 nfsd_reply_cache_shutdown(); 733 nfsd_reply_cache_shutdown();
728out_free_stat: 734out_free_stat:
729 nfsd_stat_shutdown(); 735 nfsd_stat_shutdown();
diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h
index bcb7abafbca9..3a1687251367 100644
--- a/include/linux/nfsd/export.h
+++ b/include/linux/nfsd/export.h
@@ -122,7 +122,7 @@ __be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp);
122/* 122/*
123 * Function declarations 123 * Function declarations
124 */ 124 */
125void nfsd_export_init(void); 125int nfsd_export_init(void);
126void nfsd_export_shutdown(void); 126void nfsd_export_shutdown(void);
127void nfsd_export_flush(void); 127void nfsd_export_flush(void);
128void exp_readlock(void); 128void exp_readlock(void);
diff --git a/include/linux/nfsd_idmap.h b/include/linux/nfsd_idmap.h
index e82746fcad14..d4a2ac18bd4c 100644
--- a/include/linux/nfsd_idmap.h
+++ b/include/linux/nfsd_idmap.h
@@ -44,11 +44,16 @@
44#define IDMAP_NAMESZ 128 44#define IDMAP_NAMESZ 128
45 45
46#ifdef CONFIG_NFSD_V4 46#ifdef CONFIG_NFSD_V4
47void nfsd_idmap_init(void); 47int nfsd_idmap_init(void);
48void nfsd_idmap_shutdown(void); 48void nfsd_idmap_shutdown(void);
49#else 49#else
50static inline void nfsd_idmap_init(void) {}; 50static inline int nfsd_idmap_init(void)
51static inline void nfsd_idmap_shutdown(void) {}; 51{
52 return 0;
53}
54static inline void nfsd_idmap_shutdown(void)
55{
56}
52#endif 57#endif
53 58
54int nfsd_map_name_to_uid(struct svc_rqst *, const char *, size_t, __u32 *); 59int nfsd_map_name_to_uid(struct svc_rqst *, const char *, size_t, __u32 *);
diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h
index b683b5ddeea9..03547d6abee5 100644
--- a/include/linux/sunrpc/cache.h
+++ b/include/linux/sunrpc/cache.h
@@ -169,7 +169,7 @@ extern int cache_check(struct cache_detail *detail,
169extern void cache_flush(void); 169extern void cache_flush(void);
170extern void cache_purge(struct cache_detail *detail); 170extern void cache_purge(struct cache_detail *detail);
171#define NEVER (0x7FFFFFFF) 171#define NEVER (0x7FFFFFFF)
172extern void cache_register(struct cache_detail *cd); 172extern int cache_register(struct cache_detail *cd);
173extern void cache_unregister(struct cache_detail *cd); 173extern void cache_unregister(struct cache_detail *cd);
174 174
175extern void qword_add(char **bpp, int *lp, char *str); 175extern void qword_add(char **bpp, int *lp, char *str);
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index d329a12500aa..aa790bb4f7a1 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -1386,10 +1386,19 @@ int
1386gss_svc_init(void) 1386gss_svc_init(void)
1387{ 1387{
1388 int rv = svc_auth_register(RPC_AUTH_GSS, &svcauthops_gss); 1388 int rv = svc_auth_register(RPC_AUTH_GSS, &svcauthops_gss);
1389 if (rv == 0) { 1389 if (rv)
1390 cache_register(&rsc_cache); 1390 return rv;
1391 cache_register(&rsi_cache); 1391 rv = cache_register(&rsc_cache);
1392 } 1392 if (rv)
1393 goto out1;
1394 rv = cache_register(&rsi_cache);
1395 if (rv)
1396 goto out2;
1397 return 0;
1398out2:
1399 cache_unregister(&rsc_cache);
1400out1:
1401 svc_auth_unregister(RPC_AUTH_GSS);
1393 return rv; 1402 return rv;
1394} 1403}
1395 1404
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index f41a7cc4cf62..50b1a8b441fe 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -304,20 +304,21 @@ static void remove_cache_proc_entries(struct cache_detail *cd)
304 remove_proc_entry(cd->name, proc_net_rpc); 304 remove_proc_entry(cd->name, proc_net_rpc);
305} 305}
306 306
307static void create_cache_proc_entries(struct cache_detail *cd) 307#ifdef CONFIG_PROC_FS
308static int create_cache_proc_entries(struct cache_detail *cd)
308{ 309{
309 struct proc_dir_entry *p; 310 struct proc_dir_entry *p;
310 311
311 cd->proc_ent = proc_mkdir(cd->name, proc_net_rpc); 312 cd->proc_ent = proc_mkdir(cd->name, proc_net_rpc);
312 if (cd->proc_ent == NULL) 313 if (cd->proc_ent == NULL)
313 return; 314 goto out_nomem;
314 cd->proc_ent->owner = cd->owner; 315 cd->proc_ent->owner = cd->owner;
315 cd->channel_ent = cd->content_ent = NULL; 316 cd->channel_ent = cd->content_ent = NULL;
316 317
317 p = create_proc_entry("flush", S_IFREG|S_IRUSR|S_IWUSR, cd->proc_ent); 318 p = create_proc_entry("flush", S_IFREG|S_IRUSR|S_IWUSR, cd->proc_ent);
318 cd->flush_ent = p; 319 cd->flush_ent = p;
319 if (p == NULL) 320 if (p == NULL)
320 return; 321 goto out_nomem;
321 p->proc_fops = &cache_flush_operations; 322 p->proc_fops = &cache_flush_operations;
322 p->owner = cd->owner; 323 p->owner = cd->owner;
323 p->data = cd; 324 p->data = cd;
@@ -327,7 +328,7 @@ static void create_cache_proc_entries(struct cache_detail *cd)
327 cd->proc_ent); 328 cd->proc_ent);
328 cd->channel_ent = p; 329 cd->channel_ent = p;
329 if (p == NULL) 330 if (p == NULL)
330 return; 331 goto out_nomem;
331 p->proc_fops = &cache_file_operations; 332 p->proc_fops = &cache_file_operations;
332 p->owner = cd->owner; 333 p->owner = cd->owner;
333 p->data = cd; 334 p->data = cd;
@@ -337,16 +338,30 @@ static void create_cache_proc_entries(struct cache_detail *cd)
337 cd->proc_ent); 338 cd->proc_ent);
338 cd->content_ent = p; 339 cd->content_ent = p;
339 if (p == NULL) 340 if (p == NULL)
340 return; 341 goto out_nomem;
341 p->proc_fops = &content_file_operations; 342 p->proc_fops = &content_file_operations;
342 p->owner = cd->owner; 343 p->owner = cd->owner;
343 p->data = cd; 344 p->data = cd;
344 } 345 }
346 return 0;
347out_nomem:
348 remove_cache_proc_entries(cd);
349 return -ENOMEM;
345} 350}
351#else /* CONFIG_PROC_FS */
352static int create_cache_proc_entries(struct cache_detail *cd)
353{
354 return 0;
355}
356#endif
346 357
347void cache_register(struct cache_detail *cd) 358int cache_register(struct cache_detail *cd)
348{ 359{
349 create_cache_proc_entries(cd); 360 int ret;
361
362 ret = create_cache_proc_entries(cd);
363 if (ret)
364 return ret;
350 rwlock_init(&cd->hash_lock); 365 rwlock_init(&cd->hash_lock);
351 INIT_LIST_HEAD(&cd->queue); 366 INIT_LIST_HEAD(&cd->queue);
352 spin_lock(&cache_list_lock); 367 spin_lock(&cache_list_lock);
@@ -360,6 +375,7 @@ void cache_register(struct cache_detail *cd)
360 375
361 /* start the cleaning process */ 376 /* start the cleaning process */
362 schedule_delayed_work(&cache_cleaner, 0); 377 schedule_delayed_work(&cache_cleaner, 0);
378 return 0;
363} 379}
364 380
365void cache_unregister(struct cache_detail *cd) 381void cache_unregister(struct cache_detail *cd)