Source-Changes-HG archive

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

[src/trunk]: src/sys/coda Change coda from hashlist to vcache.



details:   https://anonhg.NetBSD.org/src/rev/b97bfafe397f
branches:  trunk
changeset: 805025:b97bfafe397f
user:      hannken <hannken%NetBSD.org@localhost>
date:      Sat Dec 13 15:59:30 2014 +0000

description:
Change coda from hashlist to vcache.
- Replace all hash list crawlers with vfs_vnode_iterator.

diffstat:

 sys/coda/cnode.h       |    4 +-
 sys/coda/coda_subr.c   |  325 +++++++++++++++++++++---------------------------
 sys/coda/coda_vfsops.c |   46 +++++-
 sys/coda/coda_vfsops.h |    4 +-
 sys/coda/coda_vnops.c  |   59 ++++----
 5 files changed, 216 insertions(+), 222 deletions(-)

diffs (truncated from 713 to 300 lines):

diff -r b6ddd2bac57d -r b97bfafe397f sys/coda/cnode.h
--- a/sys/coda/cnode.h  Sat Dec 13 15:59:03 2014 +0000
+++ b/sys/coda/cnode.h  Sat Dec 13 15:59:30 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cnode.h,v 1.19 2014/12/13 15:58:13 hannken Exp $       */
+/*     $NetBSD: cnode.h,v 1.20 2014/12/13 15:59:30 hannken Exp $       */
 
 /*
  *
@@ -106,7 +106,7 @@
     u_short             c_symlen;      /* length of symbolic link */
     dev_t               c_device;      /* associated vnode device */
     ino_t               c_inode;       /* associated vnode inode */
-    struct cnode       *c_next;        /* links if on NetBSD machine */
+    kmutex_t            c_lock;
 };
 #define        VTOC(vp)        ((struct cnode *)(vp)->v_data)
 #define        SET_VTOC(vp)    ((vp)->v_data)
diff -r b6ddd2bac57d -r b97bfafe397f sys/coda/coda_subr.c
--- a/sys/coda/coda_subr.c      Sat Dec 13 15:59:03 2014 +0000
+++ b/sys/coda/coda_subr.c      Sat Dec 13 15:59:30 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: coda_subr.c,v 1.29 2014/12/13 15:58:39 hannken Exp $   */
+/*     $NetBSD: coda_subr.c,v 1.30 2014/12/13 15:59:30 hannken Exp $   */
 
 /*
  *
@@ -55,7 +55,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: coda_subr.c,v 1.29 2014/12/13 15:58:39 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: coda_subr.c,v 1.30 2014/12/13 15:59:30 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -70,22 +70,11 @@
 #include <coda/coda_subr.h>
 #include <coda/coda_namecache.h>
 
-
-int coda_active = 0;
-int coda_reuse = 0;
-int coda_new = 0;
-
-struct cnode *coda_freelist = NULL;
-struct cnode *coda_cache[CODA_CACHESIZE];
-MALLOC_DEFINE(M_CODA, "coda", "Coda file system structures and tables");
-
 int codadebug = 0;
 int coda_printf_delay = 0;  /* in microseconds */
 int coda_vnop_print_entry = 0;
 int coda_vfsop_print_entry = 0;
 
-#define        CNODE_NEXT(cp)  ((cp)->c_next)
-
 #ifdef CODA_COMPAT_5
 #define coda_hash(fid) \
     (((fid)->Volume + (fid)->Vnode) & (CODA_CACHESIZE-1))
@@ -99,99 +88,56 @@
 struct vnode *coda_ctlvp;
 
 /*
- * Allocate a cnode.
- */
-struct cnode *
-coda_alloc(void)
-{
-    struct cnode *cp;
-
-    if (coda_freelist) {
-       cp = coda_freelist;
-       coda_freelist = CNODE_NEXT(cp);
-       coda_reuse++;
-    }
-    else {
-       CODA_ALLOC(cp, struct cnode *, sizeof(struct cnode));
-       /* NetBSD vnodes don't have any Pager info in them ('cause there are
-          no external pagers, duh!) */
-#define VNODE_VM_INFO_INIT(vp)         /* MT */
-       VNODE_VM_INFO_INIT(CTOV(cp));
-       coda_new++;
-    }
-    memset(cp, 0, sizeof (struct cnode));
-
-    return(cp);
-}
-
-/*
- * Deallocate a cnode.
- */
-void
-coda_free(struct cnode *cp)
-{
-
-    CNODE_NEXT(cp) = coda_freelist;
-    coda_freelist = cp;
-}
-
-/*
- * Put a cnode in the hash table
- */
-void
-coda_save(struct cnode *cp)
-{
-       CNODE_NEXT(cp) = coda_cache[coda_hash(&cp->c_fid)];
-       coda_cache[coda_hash(&cp->c_fid)] = cp;
-}
-
-/*
- * Remove a cnode from the hash table
- */
-void
-coda_unsave(struct cnode *cp)
-{
-    struct cnode *ptr;
-    struct cnode *ptrprev = NULL;
-
-    ptr = coda_cache[coda_hash(&cp->c_fid)];
-    while (ptr != NULL) {
-       if (ptr == cp) {
-           if (ptrprev == NULL) {
-               coda_cache[coda_hash(&cp->c_fid)]
-                   = CNODE_NEXT(ptr);
-           } else {
-               CNODE_NEXT(ptrprev) = CNODE_NEXT(ptr);
-           }
-           CNODE_NEXT(cp) = NULL;
-
-           return;
-       }
-       ptrprev = ptr;
-       ptr = CNODE_NEXT(ptr);
-    }
-}
-
-/*
  * Lookup a cnode by fid. If the cnode is dying, it is bogus so skip it.
- * NOTE: this allows multiple cnodes with same fid -- dcs 1/25/95
+ * The cnode is returned locked with the vnode referenced.
  */
 struct cnode *
 coda_find(CodaFid *fid)
 {
-    struct cnode *cp;
+       int i;
+       struct vnode *vp;
+       struct cnode *cp;
+
+       for (i = 0; i < NVCODA; i++) {
+               if (!coda_mnttbl[i].mi_started)
+                       continue;
+               if (vcache_get(coda_mnttbl[i].mi_vfsp,
+                   fid, sizeof(CodaFid), &vp) != 0)
+                       continue;
+               mutex_enter(vp->v_interlock);
+               cp = VTOC(vp);
+               if (vp->v_type == VNON || cp == NULL || IS_UNMOUNTING(cp)) {
+                       mutex_exit(vp->v_interlock);
+                       vrele(vp);
+                       continue;
+               }
+               mutex_enter(&cp->c_lock);
+               mutex_exit(vp->v_interlock);
 
-    cp = coda_cache[coda_hash(fid)];
-    while (cp) {
-       if (coda_fid_eq(&(cp->c_fid), fid) &&
-           (!IS_UNMOUNTING(cp)))
-           {
-               coda_active++;
-               return(cp);
-           }
-       cp = CNODE_NEXT(cp);
-    }
-    return(NULL);
+               return cp;
+       }
+
+       return NULL;
+}
+
+/*
+ * Iterate over all nodes attached to coda mounts.
+ */
+static void
+coda_iterate(bool (*f)(void *, struct vnode *), void *cl)
+{
+       int i;
+       struct vnode_iterator *marker;
+       struct vnode *vp;
+
+       for (i = 0; i < NVCODA; i++) { 
+               if (coda_mnttbl[i].mi_vfsp == NULL)
+                       continue;
+               vfs_vnode_iterator_init(coda_mnttbl[i].mi_vfsp, &marker);
+               while ((vp = vfs_vnode_iterator_next(marker, f, cl)) != NULL)
+                       vrele(vp);
+               vfs_vnode_iterator_destroy(marker);
+       }
 }
 
 /*
@@ -203,19 +149,25 @@
  * running, only kill the cnodes for a particular entry in the
  * coda_mnttbl. -- DCS 12/1/94 */
 
+static bool
+coda_kill_selector(void *cl, struct vnode *vp)
+{
+       int *count = cl;
+
+       (*count)++;
+
+       return false;
+}
+
 int
 coda_kill(struct mount *whoIam, enum dc_status dcstat)
 {
-       int hash, count = 0;
-       struct cnode *cp;
+       int count = 0;
+       struct vnode_iterator *marker;
 
        /*
         * Algorithm is as follows:
         *     Second, flush whatever vnodes we can from the name cache.
-        *
-        *     Finally, step through whatever is left and mark them dying.
-        *        This prevents any operation at all.
-
         */
 
        /* This is slightly overkill, but should work. Eventually it'd be
@@ -223,23 +175,11 @@
         * reference a vnode in this vfs.  */
        coda_nc_flush(dcstat);
 
-       for (hash = 0; hash < CODA_CACHESIZE; hash++) {
-               for (cp = coda_cache[hash]; cp != NULL; cp = CNODE_NEXT(cp)) {
-                       if (IS_CTL_VP(CTOV(cp)))
-                               continue;
-                       if (CTOV(cp)->v_mount == whoIam) {
-#ifdef DEBUG
-                               printf("coda_kill: vp %p, cp %p\n", CTOV(cp), cp);
-#endif
-                               count++;
-                               CODADEBUG(CODA_FLUSH,
-                                        myprintf(("Live cnode fid %s flags %d count %d\n",
-                                                  coda_f2s(&cp->c_fid),
-                                                  cp->c_flags,
-                                                  CTOV(cp)->v_usecount)); );
-                       }
-               }
-       }
+
+       vfs_vnode_iterator_init(whoIam, &marker);
+       vfs_vnode_iterator_next(marker, coda_kill_selector, &count);
+       vfs_vnode_iterator_destroy(marker);
+
        return count;
 }
 
@@ -247,43 +187,48 @@
  * There are two reasons why a cnode may be in use, it may be in the
  * name cache or it may be executing.
  */
+static bool
+coda_flush_selector(void *cl, struct vnode *vp)
+{
+       struct cnode *cp = VTOC(vp);
+
+       if (cp != NULL && !IS_DIR(cp->c_fid)) /* only files can be executed */
+               coda_vmflush(cp);
+
+       return false;
+}
 void
 coda_flush(enum dc_status dcstat)
 {
-    int hash;
-    struct cnode *cp;
 
     coda_clstat.ncalls++;
     coda_clstat.reqs[CODA_FLUSH]++;
 
     coda_nc_flush(dcstat);         /* flush files from the name cache */
 
-    for (hash = 0; hash < CODA_CACHESIZE; hash++) {
-       for (cp = coda_cache[hash]; cp != NULL; cp = CNODE_NEXT(cp)) {
-           if (!IS_DIR(cp->c_fid)) /* only files can be executed */
-               coda_vmflush(cp);
-       }
-    }
+    coda_iterate(coda_flush_selector, NULL);
 }
 
 /*
  * As a debugging measure, print out any cnodes that lived through a



Home | Main Index | Thread Index | Old Index