aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@citi.umich.edu>2007-11-09 14:10:56 -0500
committerJ. Bruce Fields <bfields@citi.umich.edu>2008-02-01 16:42:04 -0500
commitd5c3428b2cb26d605fddc4878f4fcc03c23df89f (patch)
treeb476ca0b6709b65044f222912f2fdd2efbdcf297
parent26808d3f10b1213bbb6e27d441be40e20ab84611 (diff)
nfsd: fail module init on reply cache init failure
If the reply cache initialization fails due to a kmalloc failure, currently we try to soldier on with a reduced (or nonexistant) reply cache. Better to just fail immediately: the failure is then much easier to understand and debug, and it could save us complexity in some later code. (But actually, it doesn't help currently because the cache is also turned off in some odd failure cases; we should probably find a better way to handle those failure cases some day.) Fix some minor style problems while we're at it, and rename nfsd_cache_init() to remove the need for a comment describing it. Acked-by: NeilBrown <neilb@suse.de> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
-rw-r--r--fs/nfsd/nfscache.c28
-rw-r--r--fs/nfsd/nfsctl.c11
-rw-r--r--include/linux/nfsd/cache.h4
3 files changed, 21 insertions, 22 deletions
diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c
index 578f2c9d56be..5bfc2ac60d54 100644
--- a/fs/nfsd/nfscache.c
+++ b/fs/nfsd/nfscache.c
@@ -44,17 +44,17 @@ static int nfsd_cache_append(struct svc_rqst *rqstp, struct kvec *vec);
44 */ 44 */
45static DEFINE_SPINLOCK(cache_lock); 45static DEFINE_SPINLOCK(cache_lock);
46 46
47void 47int nfsd_reply_cache_init(void)
48nfsd_cache_init(void)
49{ 48{
50 struct svc_cacherep *rp; 49 struct svc_cacherep *rp;
51 int i; 50 int i;
52 51
53 INIT_LIST_HEAD(&lru_head); 52 INIT_LIST_HEAD(&lru_head);
54 i = CACHESIZE; 53 i = CACHESIZE;
55 while(i) { 54 while (i) {
56 rp = kmalloc(sizeof(*rp), GFP_KERNEL); 55 rp = kmalloc(sizeof(*rp), GFP_KERNEL);
57 if (!rp) break; 56 if (!rp)
57 goto out_nomem;
58 list_add(&rp->c_lru, &lru_head); 58 list_add(&rp->c_lru, &lru_head);
59 rp->c_state = RC_UNUSED; 59 rp->c_state = RC_UNUSED;
60 rp->c_type = RC_NOCACHE; 60 rp->c_type = RC_NOCACHE;
@@ -62,23 +62,19 @@ nfsd_cache_init(void)
62 i--; 62 i--;
63 } 63 }
64 64
65 if (i)
66 printk (KERN_ERR "nfsd: cannot allocate all %d cache entries, only got %d\n",
67 CACHESIZE, CACHESIZE-i);
68
69 hash_list = kcalloc (HASHSIZE, sizeof(struct hlist_head), GFP_KERNEL); 65 hash_list = kcalloc (HASHSIZE, sizeof(struct hlist_head), GFP_KERNEL);
70 if (!hash_list) { 66 if (!hash_list)
71 nfsd_cache_shutdown(); 67 goto out_nomem;
72 printk (KERN_ERR "nfsd: cannot allocate %Zd bytes for hash list\n",
73 HASHSIZE * sizeof(struct hlist_head));
74 return;
75 }
76 68
77 cache_disabled = 0; 69 cache_disabled = 0;
70 return 0;
71out_nomem:
72 printk(KERN_ERR "nfsd: failed to allocate reply cache\n");
73 nfsd_reply_cache_shutdown();
74 return -ENOMEM;
78} 75}
79 76
80void 77void nfsd_reply_cache_shutdown(void)
81nfsd_cache_shutdown(void)
82{ 78{
83 struct svc_cacherep *rp; 79 struct svc_cacherep *rp;
84 80
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index ecf377944286..2bfda9b8f504 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -683,7 +683,9 @@ static int __init init_nfsd(void)
683 if (retval) 683 if (retval)
684 return retval; 684 return retval;
685 nfsd_stat_init(); /* Statistics */ 685 nfsd_stat_init(); /* Statistics */
686 nfsd_cache_init(); /* RPC reply cache */ 686 retval = nfsd_reply_cache_init();
687 if (retval)
688 goto out_free_stat;
687 nfsd_export_init(); /* Exports table */ 689 nfsd_export_init(); /* Exports table */
688 nfsd_lockd_init(); /* lockd->nfsd callbacks */ 690 nfsd_lockd_init(); /* lockd->nfsd callbacks */
689 nfsd_idmap_init(); /* Name to ID mapping */ 691 nfsd_idmap_init(); /* Name to ID mapping */
@@ -700,11 +702,12 @@ static int __init init_nfsd(void)
700out_free_all: 702out_free_all:
701 nfsd_idmap_shutdown(); 703 nfsd_idmap_shutdown();
702 nfsd_export_shutdown(); 704 nfsd_export_shutdown();
703 nfsd_cache_shutdown(); 705 nfsd_reply_cache_shutdown();
704 remove_proc_entry("fs/nfs/exports", NULL); 706 remove_proc_entry("fs/nfs/exports", NULL);
705 remove_proc_entry("fs/nfs", NULL); 707 remove_proc_entry("fs/nfs", NULL);
706 nfsd_stat_shutdown();
707 nfsd_lockd_shutdown(); 708 nfsd_lockd_shutdown();
709out_free_stat:
710 nfsd_stat_shutdown();
708 nfsd4_free_slabs(); 711 nfsd4_free_slabs();
709 return retval; 712 return retval;
710} 713}
@@ -712,7 +715,7 @@ out_free_all:
712static void __exit exit_nfsd(void) 715static void __exit exit_nfsd(void)
713{ 716{
714 nfsd_export_shutdown(); 717 nfsd_export_shutdown();
715 nfsd_cache_shutdown(); 718 nfsd_reply_cache_shutdown();
716 remove_proc_entry("fs/nfs/exports", NULL); 719 remove_proc_entry("fs/nfs/exports", NULL);
717 remove_proc_entry("fs/nfs", NULL); 720 remove_proc_entry("fs/nfs", NULL);
718 nfsd_stat_shutdown(); 721 nfsd_stat_shutdown();
diff --git a/include/linux/nfsd/cache.h b/include/linux/nfsd/cache.h
index 007480cd6a60..7b5d784cc858 100644
--- a/include/linux/nfsd/cache.h
+++ b/include/linux/nfsd/cache.h
@@ -72,8 +72,8 @@ enum {
72 */ 72 */
73#define RC_DELAY (HZ/5) 73#define RC_DELAY (HZ/5)
74 74
75void nfsd_cache_init(void); 75int nfsd_reply_cache_init(void);
76void nfsd_cache_shutdown(void); 76void nfsd_reply_cache_shutdown(void);
77int nfsd_cache_lookup(struct svc_rqst *, int); 77int nfsd_cache_lookup(struct svc_rqst *, int);
78void nfsd_cache_update(struct svc_rqst *, int, __be32 *); 78void nfsd_cache_update(struct svc_rqst *, int, __be32 *);
79 79