Skip to content

Commit

Permalink
knfsd: allow cache_register to return error on failure
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
J. Bruce Fields committed Feb 1, 2008
1 parent ffe9386 commit dbf847e
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 25 deletions.
12 changes: 9 additions & 3 deletions fs/nfsd/export.c
Original file line number Diff line number Diff line change
Expand Up @@ -1637,13 +1637,19 @@ exp_verify_string(char *cp, int max)
/*
* Initialize the exports module.
*/
void
int
nfsd_export_init(void)
{
int rv;
dprintk("nfsd: initializing export module.\n");

cache_register(&svc_export_cache);
cache_register(&svc_expkey_cache);
rv = cache_register(&svc_export_cache);
if (rv)
return rv;
rv = cache_register(&svc_expkey_cache);
if (rv)
cache_unregister(&svc_export_cache);
return rv;

}

Expand Down
13 changes: 10 additions & 3 deletions fs/nfsd/nfs4idmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -464,11 +464,18 @@ nametoid_update(struct ent *new, struct ent *old)
* Exported API
*/

void
int
nfsd_idmap_init(void)
{
cache_register(&idtoname_cache);
cache_register(&nametoid_cache);
int rv;

rv = cache_register(&idtoname_cache);
if (rv)
return rv;
rv = cache_register(&nametoid_cache);
if (rv)
cache_unregister(&idtoname_cache);
return rv;
}

void
Expand Down
12 changes: 9 additions & 3 deletions fs/nfsd/nfsctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -707,9 +707,13 @@ static int __init init_nfsd(void)
retval = nfsd_reply_cache_init();
if (retval)
goto out_free_stat;
nfsd_export_init(); /* Exports table */
retval = nfsd_export_init();
if (retval)
goto out_free_cache;
nfsd_lockd_init(); /* lockd->nfsd callbacks */
nfsd_idmap_init(); /* Name to ID mapping */
retval = nfsd_idmap_init();
if (retval)
goto out_free_lockd;
retval = create_proc_exports_entry();
if (retval)
goto out_free_idmap;
Expand All @@ -720,10 +724,12 @@ static int __init init_nfsd(void)
out_free_all:
remove_proc_entry("fs/nfs/exports", NULL);
remove_proc_entry("fs/nfs", NULL);
nfsd_idmap_shutdown();
out_free_idmap:
nfsd_idmap_shutdown();
out_free_lockd:
nfsd_lockd_shutdown();
nfsd_export_shutdown();
out_free_cache:
nfsd_reply_cache_shutdown();
out_free_stat:
nfsd_stat_shutdown();
Expand Down
2 changes: 1 addition & 1 deletion include/linux/nfsd/export.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ __be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp);
/*
* Function declarations
*/
void nfsd_export_init(void);
int nfsd_export_init(void);
void nfsd_export_shutdown(void);
void nfsd_export_flush(void);
void exp_readlock(void);
Expand Down
11 changes: 8 additions & 3 deletions include/linux/nfsd_idmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,16 @@
#define IDMAP_NAMESZ 128

#ifdef CONFIG_NFSD_V4
void nfsd_idmap_init(void);
int nfsd_idmap_init(void);
void nfsd_idmap_shutdown(void);
#else
static inline void nfsd_idmap_init(void) {};
static inline void nfsd_idmap_shutdown(void) {};
static inline int nfsd_idmap_init(void)
{
return 0;
}
static inline void nfsd_idmap_shutdown(void)
{
}
#endif

int nfsd_map_name_to_uid(struct svc_rqst *, const char *, size_t, __u32 *);
Expand Down
2 changes: 1 addition & 1 deletion include/linux/sunrpc/cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ extern int cache_check(struct cache_detail *detail,
extern void cache_flush(void);
extern void cache_purge(struct cache_detail *detail);
#define NEVER (0x7FFFFFFF)
extern void cache_register(struct cache_detail *cd);
extern int cache_register(struct cache_detail *cd);
extern void cache_unregister(struct cache_detail *cd);

extern void qword_add(char **bpp, int *lp, char *str);
Expand Down
17 changes: 13 additions & 4 deletions net/sunrpc/auth_gss/svcauth_gss.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
30 changes: 23 additions & 7 deletions net/sunrpc/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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);
Expand All @@ -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)
Expand Down

0 comments on commit dbf847e

Please sign in to comment.