Module Name: src
Committed By: christos
Date: Wed Sep 18 16:33:14 UTC 2013
Modified Files:
src/sys/nfs: nfs_subs.c
Log Message:
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.
To generate a diff of this commit:
cvs rdiff -u -r1.222 -r1.223 src/sys/nfs/nfs_subs.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/nfs/nfs_subs.c
diff -u src/sys/nfs/nfs_subs.c:1.222 src/sys/nfs/nfs_subs.c:1.223
--- src/sys/nfs/nfs_subs.c:1.222 Sat Nov 19 17:51:30 2011
+++ src/sys/nfs/nfs_subs.c Wed Sep 18 12:33:14 2013
@@ -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();
}
/*