Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/nfs Use reference counting to keep track of construction...



details:   https://anonhg.NetBSD.org/src/rev/a4741ae703d1
branches:  trunk
changeset: 790094:a4741ae703d1
user:      christos <christos%NetBSD.org@localhost>
date:      Wed Sep 18 16:33:14 2013 +0000

description:
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.

diffstat:

 sys/nfs/nfs_subs.c |  33 +++++++++++++++++++++++----------
 1 files changed, 23 insertions(+), 10 deletions(-)

diffs (67 lines):

diff -r e4bd8a118bec -r a4741ae703d1 sys/nfs/nfs_subs.c
--- a/sys/nfs/nfs_subs.c        Wed Sep 18 14:37:24 2013 +0000
+++ b/sys/nfs/nfs_subs.c        Wed Sep 18 16:33:14 2013 +0000
@@ -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 @@
        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();
 }
 
 /*



Home | Main Index | Thread Index | Old Index