Skip to content

Commit dbf847e

Browse files
author
J. Bruce Fields
committed
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 <[email protected]> Acked-by: NeilBrown <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
1 parent ffe9386 commit dbf847e

File tree

8 files changed

+74
-25
lines changed

8 files changed

+74
-25
lines changed

fs/nfsd/export.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,13 +1637,19 @@ exp_verify_string(char *cp, int max)
16371637
/*
16381638
* Initialize the exports module.
16391639
*/
1640-
void
1640+
int
16411641
nfsd_export_init(void)
16421642
{
1643+
int rv;
16431644
dprintk("nfsd: initializing export module.\n");
16441645

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;
16471653

16481654
}
16491655

fs/nfsd/nfs4idmap.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -464,11 +464,18 @@ nametoid_update(struct ent *new, struct ent *old)
464464
* Exported API
465465
*/
466466

467-
void
467+
int
468468
nfsd_idmap_init(void)
469469
{
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;
472479
}
473480

474481
void

fs/nfsd/nfsctl.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -707,9 +707,13 @@ static int __init init_nfsd(void)
707707
retval = nfsd_reply_cache_init();
708708
if (retval)
709709
goto out_free_stat;
710-
nfsd_export_init(); /* Exports table */
710+
retval = nfsd_export_init();
711+
if (retval)
712+
goto out_free_cache;
711713
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;
713717
retval = create_proc_exports_entry();
714718
if (retval)
715719
goto out_free_idmap;
@@ -720,10 +724,12 @@ static int __init init_nfsd(void)
720724
out_free_all:
721725
remove_proc_entry("fs/nfs/exports", NULL);
722726
remove_proc_entry("fs/nfs", NULL);
723-
nfsd_idmap_shutdown();
724727
out_free_idmap:
728+
nfsd_idmap_shutdown();
729+
out_free_lockd:
725730
nfsd_lockd_shutdown();
726731
nfsd_export_shutdown();
732+
out_free_cache:
727733
nfsd_reply_cache_shutdown();
728734
out_free_stat:
729735
nfsd_stat_shutdown();

include/linux/nfsd/export.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ __be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp);
122122
/*
123123
* Function declarations
124124
*/
125-
void nfsd_export_init(void);
125+
int nfsd_export_init(void);
126126
void nfsd_export_shutdown(void);
127127
void nfsd_export_flush(void);
128128
void exp_readlock(void);

include/linux/nfsd_idmap.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,16 @@
4444
#define IDMAP_NAMESZ 128
4545

4646
#ifdef CONFIG_NFSD_V4
47-
void nfsd_idmap_init(void);
47+
int nfsd_idmap_init(void);
4848
void nfsd_idmap_shutdown(void);
4949
#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+
}
5257
#endif
5358

5459
int nfsd_map_name_to_uid(struct svc_rqst *, const char *, size_t, __u32 *);

include/linux/sunrpc/cache.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ extern int cache_check(struct cache_detail *detail,
169169
extern void cache_flush(void);
170170
extern void cache_purge(struct cache_detail *detail);
171171
#define NEVER (0x7FFFFFFF)
172-
extern void cache_register(struct cache_detail *cd);
172+
extern int cache_register(struct cache_detail *cd);
173173
extern void cache_unregister(struct cache_detail *cd);
174174

175175
extern void qword_add(char **bpp, int *lp, char *str);

net/sunrpc/auth_gss/svcauth_gss.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,10 +1386,19 @@ int
13861386
gss_svc_init(void)
13871387
{
13881388
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);
13931402
return rv;
13941403
}
13951404

net/sunrpc/cache.c

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -304,20 +304,21 @@ static void remove_cache_proc_entries(struct cache_detail *cd)
304304
remove_proc_entry(cd->name, proc_net_rpc);
305305
}
306306

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)
308309
{
309310
struct proc_dir_entry *p;
310311

311312
cd->proc_ent = proc_mkdir(cd->name, proc_net_rpc);
312313
if (cd->proc_ent == NULL)
313-
return;
314+
goto out_nomem;
314315
cd->proc_ent->owner = cd->owner;
315316
cd->channel_ent = cd->content_ent = NULL;
316317

317318
p = create_proc_entry("flush", S_IFREG|S_IRUSR|S_IWUSR, cd->proc_ent);
318319
cd->flush_ent = p;
319320
if (p == NULL)
320-
return;
321+
goto out_nomem;
321322
p->proc_fops = &cache_flush_operations;
322323
p->owner = cd->owner;
323324
p->data = cd;
@@ -327,7 +328,7 @@ static void create_cache_proc_entries(struct cache_detail *cd)
327328
cd->proc_ent);
328329
cd->channel_ent = p;
329330
if (p == NULL)
330-
return;
331+
goto out_nomem;
331332
p->proc_fops = &cache_file_operations;
332333
p->owner = cd->owner;
333334
p->data = cd;
@@ -337,16 +338,30 @@ static void create_cache_proc_entries(struct cache_detail *cd)
337338
cd->proc_ent);
338339
cd->content_ent = p;
339340
if (p == NULL)
340-
return;
341+
goto out_nomem;
341342
p->proc_fops = &content_file_operations;
342343
p->owner = cd->owner;
343344
p->data = cd;
344345
}
346+
return 0;
347+
out_nomem:
348+
remove_cache_proc_entries(cd);
349+
return -ENOMEM;
345350
}
351+
#else /* CONFIG_PROC_FS */
352+
static int create_cache_proc_entries(struct cache_detail *cd)
353+
{
354+
return 0;
355+
}
356+
#endif
346357

347-
void cache_register(struct cache_detail *cd)
358+
int cache_register(struct cache_detail *cd)
348359
{
349-
create_cache_proc_entries(cd);
360+
int ret;
361+
362+
ret = create_cache_proc_entries(cd);
363+
if (ret)
364+
return ret;
350365
rwlock_init(&cd->hash_lock);
351366
INIT_LIST_HEAD(&cd->queue);
352367
spin_lock(&cache_list_lock);
@@ -360,6 +375,7 @@ void cache_register(struct cache_detail *cd)
360375

361376
/* start the cleaning process */
362377
schedule_delayed_work(&cache_cleaner, 0);
378+
return 0;
363379
}
364380

365381
void cache_unregister(struct cache_detail *cd)

0 commit comments

Comments
 (0)