Commit dbf847ecb6318d3a22c6758fe39696d00f39063a

Authored by J. Bruce Fields
1 parent ffe9386b6e

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>

Showing 8 changed files with 74 additions and 25 deletions Side-by-side Diff

... ... @@ -1637,13 +1637,19 @@
1637 1637 /*
1638 1638 * Initialize the exports module.
1639 1639 */
1640   -void
  1640 +int
1641 1641 nfsd_export_init(void)
1642 1642 {
  1643 + int rv;
1643 1644 dprintk("nfsd: initializing export module.\n");
1644 1645  
1645   - cache_register(&svc_export_cache);
1646   - cache_register(&svc_expkey_cache);
  1646 + rv = cache_register(&svc_export_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  
... ... @@ -464,11 +464,18 @@
464 464 * Exported API
465 465 */
466 466  
467   -void
  467 +int
468 468 nfsd_idmap_init(void)
469 469 {
470   - cache_register(&idtoname_cache);
471   - cache_register(&nametoid_cache);
  470 + int rv;
  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  
474 481 void
... ... @@ -707,9 +707,13 @@
707 707 retval = nfsd_reply_cache_init();
708 708 if (retval)
709 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 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 717 retval = create_proc_exports_entry();
714 718 if (retval)
715 719 goto out_free_idmap;
716 720  
717 721  
... ... @@ -720,10 +724,12 @@
720 724 out_free_all:
721 725 remove_proc_entry("fs/nfs/exports", NULL);
722 726 remove_proc_entry("fs/nfs", NULL);
723   - nfsd_idmap_shutdown();
724 727 out_free_idmap:
  728 + nfsd_idmap_shutdown();
  729 +out_free_lockd:
725 730 nfsd_lockd_shutdown();
726 731 nfsd_export_shutdown();
  732 +out_free_cache:
727 733 nfsd_reply_cache_shutdown();
728 734 out_free_stat:
729 735 nfsd_stat_shutdown();
include/linux/nfsd/export.h
... ... @@ -122,7 +122,7 @@
122 122 /*
123 123 * Function declarations
124 124 */
125   -void nfsd_export_init(void);
  125 +int nfsd_export_init(void);
126 126 void nfsd_export_shutdown(void);
127 127 void nfsd_export_flush(void);
128 128 void exp_readlock(void);
include/linux/nfsd_idmap.h
... ... @@ -44,11 +44,16 @@
44 44 #define IDMAP_NAMESZ 128
45 45  
46 46 #ifdef CONFIG_NFSD_V4
47   -void nfsd_idmap_init(void);
  47 +int nfsd_idmap_init(void);
48 48 void nfsd_idmap_shutdown(void);
49 49 #else
50   -static inline void nfsd_idmap_init(void) {};
51   -static inline void nfsd_idmap_shutdown(void) {};
  50 +static inline int nfsd_idmap_init(void)
  51 +{
  52 + return 0;
  53 +}
  54 +static inline void nfsd_idmap_shutdown(void)
  55 +{
  56 +}
52 57 #endif
53 58  
54 59 int nfsd_map_name_to_uid(struct svc_rqst *, const char *, size_t, __u32 *);
include/linux/sunrpc/cache.h
... ... @@ -169,7 +169,7 @@
169 169 extern void cache_flush(void);
170 170 extern void cache_purge(struct cache_detail *detail);
171 171 #define NEVER (0x7FFFFFFF)
172   -extern void cache_register(struct cache_detail *cd);
  172 +extern int cache_register(struct cache_detail *cd);
173 173 extern void cache_unregister(struct cache_detail *cd);
174 174  
175 175 extern void qword_add(char **bpp, int *lp, char *str);
net/sunrpc/auth_gss/svcauth_gss.c
... ... @@ -1386,10 +1386,19 @@
1386 1386 gss_svc_init(void)
1387 1387 {
1388 1388 int rv = svc_auth_register(RPC_AUTH_GSS, &svcauthops_gss);
1389   - if (rv == 0) {
1390   - cache_register(&rsc_cache);
1391   - cache_register(&rsi_cache);
1392   - }
  1389 + if (rv)
  1390 + return rv;
  1391 + rv = cache_register(&rsc_cache);
  1392 + if (rv)
  1393 + goto out1;
  1394 + rv = cache_register(&rsi_cache);
  1395 + if (rv)
  1396 + goto out2;
  1397 + return 0;
  1398 +out2:
  1399 + cache_unregister(&rsc_cache);
  1400 +out1:
  1401 + svc_auth_unregister(RPC_AUTH_GSS);
1393 1402 return rv;
1394 1403 }
1395 1404  
... ... @@ -304,20 +304,21 @@
304 304 remove_proc_entry(cd->name, proc_net_rpc);
305 305 }
306 306  
307   -static void create_cache_proc_entries(struct cache_detail *cd)
  307 +#ifdef CONFIG_PROC_FS
  308 +static int create_cache_proc_entries(struct cache_detail *cd)
308 309 {
309 310 struct proc_dir_entry *p;
310 311  
311 312 cd->proc_ent = proc_mkdir(cd->name, proc_net_rpc);
312 313 if (cd->proc_ent == NULL)
313   - return;
  314 + goto out_nomem;
314 315 cd->proc_ent->owner = cd->owner;
315 316 cd->channel_ent = cd->content_ent = NULL;
316 317  
317 318 p = create_proc_entry("flush", S_IFREG|S_IRUSR|S_IWUSR, cd->proc_ent);
318 319 cd->flush_ent = p;
319 320 if (p == NULL)
320   - return;
  321 + goto out_nomem;
321 322 p->proc_fops = &cache_flush_operations;
322 323 p->owner = cd->owner;
323 324 p->data = cd;
... ... @@ -327,7 +328,7 @@
327 328 cd->proc_ent);
328 329 cd->channel_ent = p;
329 330 if (p == NULL)
330   - return;
  331 + goto out_nomem;
331 332 p->proc_fops = &cache_file_operations;
332 333 p->owner = cd->owner;
333 334 p->data = cd;
334 335  
335 336  
336 337  
337 338  
... ... @@ -337,16 +338,30 @@
337 338 cd->proc_ent);
338 339 cd->content_ent = p;
339 340 if (p == NULL)
340   - return;
  341 + goto out_nomem;
341 342 p->proc_fops = &content_file_operations;
342 343 p->owner = cd->owner;
343 344 p->data = cd;
344 345 }
  346 + return 0;
  347 +out_nomem:
  348 + remove_cache_proc_entries(cd);
  349 + return -ENOMEM;
345 350 }
  351 +#else /* CONFIG_PROC_FS */
  352 +static int create_cache_proc_entries(struct cache_detail *cd)
  353 +{
  354 + return 0;
  355 +}
  356 +#endif
346 357  
347   -void cache_register(struct cache_detail *cd)
  358 +int 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 365 rwlock_init(&cd->hash_lock);
351 366 INIT_LIST_HEAD(&cd->queue);
352 367 spin_lock(&cache_list_lock);
... ... @@ -360,6 +375,7 @@
360 375  
361 376 /* start the cleaning process */
362 377 schedule_delayed_work(&cache_cleaner, 0);
  378 + return 0;
363 379 }
364 380  
365 381 void cache_unregister(struct cache_detail *cd)