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/80b76d94f16a
branches: trunk
changeset: 334883:80b76d94f16a
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 be06d1a48789 -r 80b76d94f16a 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 be06d1a48789 -r 80b76d94f16a 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