diff options
author | J. Bruce Fields <bfields@citi.umich.edu> | 2007-11-08 17:20:34 -0500 |
---|---|---|
committer | J. Bruce Fields <bfields@citi.umich.edu> | 2008-02-01 16:42:05 -0500 |
commit | dbf847ecb6318d3a22c6758fe39696d00f39063a (patch) | |
tree | 2b71e776ca98bc94258f3539bd7f0ea53d2733a8 /net | |
parent | ffe9386b6e08e7132cb7730025d0ea310e08a182 (diff) | |
download | linux-dbf847ecb6318d3a22c6758fe39696d00f39063a.tar.bz2 |
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>
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/auth_gss/svcauth_gss.c | 17 | ||||
-rw-r--r-- | net/sunrpc/cache.c | 30 |
2 files changed, 36 insertions, 11 deletions
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 gss_svc_init(void) { int rv = svc_auth_register(RPC_AUTH_GSS, &svcauthops_gss); - if (rv == 0) { - cache_register(&rsc_cache); - cache_register(&rsi_cache); - } + if (rv) + return rv; + rv = cache_register(&rsc_cache); + if (rv) + goto out1; + rv = cache_register(&rsi_cache); + if (rv) + goto out2; + return 0; +out2: + cache_unregister(&rsc_cache); +out1: + svc_auth_unregister(RPC_AUTH_GSS); return rv; } 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) remove_proc_entry(cd->name, proc_net_rpc); } -static void create_cache_proc_entries(struct cache_detail *cd) +#ifdef CONFIG_PROC_FS +static int create_cache_proc_entries(struct cache_detail *cd) { struct proc_dir_entry *p; cd->proc_ent = proc_mkdir(cd->name, proc_net_rpc); if (cd->proc_ent == NULL) - return; + goto out_nomem; cd->proc_ent->owner = cd->owner; cd->channel_ent = cd->content_ent = NULL; p = create_proc_entry("flush", S_IFREG|S_IRUSR|S_IWUSR, cd->proc_ent); cd->flush_ent = p; if (p == NULL) - return; + goto out_nomem; p->proc_fops = &cache_flush_operations; p->owner = cd->owner; p->data = cd; @@ -327,7 +328,7 @@ static void create_cache_proc_entries(struct cache_detail *cd) cd->proc_ent); cd->channel_ent = p; if (p == NULL) - return; + goto out_nomem; p->proc_fops = &cache_file_operations; p->owner = cd->owner; p->data = cd; @@ -337,16 +338,30 @@ static void create_cache_proc_entries(struct cache_detail *cd) cd->proc_ent); cd->content_ent = p; if (p == NULL) - return; + goto out_nomem; p->proc_fops = &content_file_operations; p->owner = cd->owner; p->data = cd; } + return 0; +out_nomem: + remove_cache_proc_entries(cd); + return -ENOMEM; } +#else /* CONFIG_PROC_FS */ +static int create_cache_proc_entries(struct cache_detail *cd) +{ + return 0; +} +#endif -void cache_register(struct cache_detail *cd) +int cache_register(struct cache_detail *cd) { - create_cache_proc_entries(cd); + int ret; + + ret = create_cache_proc_entries(cd); + if (ret) + return ret; rwlock_init(&cd->hash_lock); INIT_LIST_HEAD(&cd->queue); spin_lock(&cache_list_lock); @@ -360,6 +375,7 @@ void cache_register(struct cache_detail *cd) /* start the cleaning process */ schedule_delayed_work(&cache_cleaner, 0); + return 0; } void cache_unregister(struct cache_detail *cd) |