Use reference counting to keep track of construction and destruction of the
structures used by both the nfs server and client code. Tested by pgoyette@ 1. mount remote fs via nfs (my /home directory), which autoloads nfs module 2. manually modload nfsserver 3. wait a bit 4. manually modunload nfsserver 5. wait a couple minutes 6. verify that client access still works (/bin/ls ~paul home dir) 7. manually modload nfsserver again 8. start an nfsd process 9. wait a bit 10. kill nfsd process 11. wait 12. manually modunload nfsserver again 13. verify continued client access XXX: Note that nfs_vfs_init() calls nfs_init(), but nfs_vfs_done() does not call nfs_fini(). Also note that the destruction order is wrong in it, but probably does not matter. "someone" (!= me) should fix it :-) and run the above tests.
This commit is contained in:
parent
8ff352ec00
commit
0105cbeff0
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: nfs_subs.c,v 1.222 2011/11/19 22:51:30 tls Exp $ */
|
||||
/* $NetBSD: nfs_subs.c,v 1.223 2013/09/18 16:33:14 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
@ -70,7 +70,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: nfs_subs.c,v 1.222 2011/11/19 22:51:30 tls Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: nfs_subs.c,v 1.223 2013/09/18 16:33:14 christos Exp $");
|
||||
|
||||
#ifdef _KERNEL_OPT
|
||||
#include "opt_nfs.h"
|
||||
@ -1502,27 +1502,40 @@ nfs_init0(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static volatile uint32_t nfs_mutex;
|
||||
static uint32_t nfs_refcount;
|
||||
|
||||
#define nfs_p() while (atomic_cas_32(&nfs_mutex, 0, 1) == 0) continue;
|
||||
#define nfs_v() while (atomic_cas_32(&nfs_mutex, 1, 0) == 1) continue;
|
||||
|
||||
/*
|
||||
* This is disgusting, but it must support both modular and monolothic
|
||||
* configurations. For monolithic builds NFSSERVER may not imply NFS.
|
||||
* configurations, plus the code is shared between server and client.
|
||||
* For monolithic builds NFSSERVER may not imply NFS. Unfortunately we
|
||||
* can't use regular mutexes here that would require static initialization
|
||||
* and we can get initialized from multiple places, so we improvise.
|
||||
*
|
||||
* Yuck.
|
||||
*/
|
||||
void
|
||||
nfs_init(void)
|
||||
{
|
||||
static ONCE_DECL(nfs_init_once);
|
||||
|
||||
RUN_ONCE(&nfs_init_once, nfs_init0);
|
||||
nfs_p();
|
||||
if (nfs_refcount++ == 0)
|
||||
nfs_init0();
|
||||
nfs_v();
|
||||
}
|
||||
|
||||
void
|
||||
nfs_fini(void)
|
||||
{
|
||||
|
||||
nfsdreq_fini();
|
||||
nfs_timer_fini();
|
||||
MOWNER_DETACH(&nfs_mowner);
|
||||
nfs_p();
|
||||
if (--nfs_refcount == 0) {
|
||||
MOWNER_DETACH(&nfs_mowner);
|
||||
nfs_timer_fini();
|
||||
nfsdreq_fini();
|
||||
}
|
||||
nfs_v();
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user