From owner-p4-projects@FreeBSD.ORG Thu Aug 12 12:51:27 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id A77881065694; Thu, 12 Aug 2010 12:51:27 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 6B38E106564A for ; Thu, 12 Aug 2010 12:51:27 +0000 (UTC) (envelope-from gk@FreeBSD.org) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:4f8:fff6::2d]) by mx1.freebsd.org (Postfix) with ESMTP id 571DF8FC1C for ; Thu, 12 Aug 2010 12:51:27 +0000 (UTC) Received: from skunkworks.freebsd.org (localhost [127.0.0.1]) by skunkworks.freebsd.org (8.14.4/8.14.4) with ESMTP id o7CCpRXA024079 for ; Thu, 12 Aug 2010 12:51:27 GMT (envelope-from gk@FreeBSD.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.4/8.14.4/Submit) id o7CCpRtv024076 for perforce@freebsd.org; Thu, 12 Aug 2010 12:51:27 GMT (envelope-from gk@FreeBSD.org) Date: Thu, 12 Aug 2010 12:51:27 GMT Message-Id: <201008121251.o7CCpRtv024076@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to gk@FreeBSD.org using -f From: Gleb Kurtsou To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 182315 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 12 Aug 2010 12:51:27 -0000 http://p4web.freebsd.org/@@182315?ac=10 Change 182315 by gk@gk_h1 on 2010/08/12 12:50:31 Fix weak-only cache and bug in tmpfs. Remove root node type Affected files ... .. //depot/projects/soc2010/gk_namecache/sys/fs/tmpfs/tmpfs_vnops.c#7 edit .. //depot/projects/soc2010/gk_namecache/sys/kern/vfs_dircache.c#10 edit .. //depot/projects/soc2010/gk_namecache/sys/modules/tmpfs/Makefile#6 edit .. //depot/projects/soc2010/gk_namecache/sys/sys/dircache.h#10 edit Differences ... ==== //depot/projects/soc2010/gk_namecache/sys/fs/tmpfs/tmpfs_vnops.c#7 (text+ko) ==== @@ -991,10 +991,14 @@ fnode = VP_TO_TMPFS_NODE(fvp); de = tmpfs_dir_lookup(fdnode, fnode, fcnp); - /* Avoid manipulating '.' and '..' entries. */ + /* Entry can disappear before we lock fdvp, + * also avoid manipulating '.' and '..' entries. */ if (de == NULL) { - MPASS(fvp->v_type == VDIR); - error = EINVAL; + if ((fcnp->cn_flags & ISDOTDOT) != 0 || + (fcnp->cn_namelen == 1 && fcnp->cn_nameptr[0] == '.')) + error = EINVAL; + else + error = ENOENT; goto out_locked; } MPASS(de->td_node == fnode); ==== //depot/projects/soc2010/gk_namecache/sys/kern/vfs_dircache.c#10 (text+ko) ==== @@ -53,8 +53,8 @@ #define DC_NAMEROUND 32 /* power of 2 */ -#define DC_OP_LOCKPREF 0x00000001 -#define DC_OP_CREATEREF 0x00000002 +#define DC_LOCKPREF 0x00000001 +#define DC_CREATEREF 0x00000002 #define DP_UNUSED_MIN 512 #define DP_THRESHOLD_DFLT 256 @@ -352,7 +352,7 @@ return (dr); } -static __inline void +static __inline int dr_drop(struct dircache_ref *dr) { struct dircache_mount *dm = dr->dr_mount; @@ -362,14 +362,17 @@ if (dr->dr_vnode == NULL && LIST_EMPTY(&dr->dr_entries) && dr != dm->dm_rootref && dr != dm->dm_negativeref) { MPASS(RB_EMPTY(&dr->dr_children)); + DCDEBUG("free ref %p\n", dr); dr_unlock(dr); dm_lock(dm); dr_mntq_remove(dr); dm_unlock(dm); mtx_destroy(&dr->dr_mtx); uma_zfree(dircache_ref_zone, dr); - } else - dr_unlock(dr); + return (1); + } + dr_unlock(dr); + return (0); } @@ -379,15 +382,17 @@ struct dircache_ref *dr; dr = vp->v_dircache; - if (dr == NULL && (flags & DC_OP_CREATEREF) != 0 && + if (dr == NULL && (flags & DC_CREATEREF) != 0 && (vp->v_mount->mnt_kern_flag & MNTK_DIRCACHE) == 0) { + DCDEBUG("dr_get: allocate weak ref: vp=%p\n", vp); dircache_allocvnode(vp, 0); dr = vp->v_dircache; } if (dr != NULL) { dr_lock(dr); MPASS(vp->v_dircache == dr); - } + } else + DCDEBUG("dr_get: NULL result\n"); return (dr); } @@ -713,7 +718,7 @@ struct dircache_ref *dr; struct dircache *dc; - dr = dr_get(vp, DC_OP_CREATEREF); + dr = dr_get(vp, DC_CREATEREF); dc = LIST_FIRST(&dr->dr_entries); if (dc == NULL) { dr_unlock(dr); @@ -773,13 +778,13 @@ struct dircache_ref *parentref; struct dircache *dc; - parentref = dr_get(dvp, DC_OP_CREATEREF); + parentref = dr_get(dvp, DC_CREATEREF); dc_initname(&key, cnp->cn_nameptr, cnp->cn_namelen); dc = RB_FIND(dircache_tree, &parentref->dr_children, &key); if (dc != NULL) { dc_lock(dc); - if ((flags & DC_OP_LOCKPREF) == 0) + if ((flags & DC_LOCKPREF) == 0) dr_unlock(parentref); } else dr_unlock(parentref); @@ -808,9 +813,9 @@ MPASS(dc->dc_parentref != NULL); dc_assertlock(dc, MA_OWNED); dr_assertlock(dc->dc_parentref, MA_OWNED); - dc_assertempty(dc); - DCDEBUG("remove entry: %p %s\n", dc, dc->dc_name); + DCDEBUG("remove entry: dc=%p ref=%p parentref=%p %s\n", + dc, dc->dc_selfref, dc->dc_parentref, dc->dc_name); parentref = dc->dc_parentref; dc->dc_parentref = NULL; RB_REMOVE(dircache_tree, &parentref->dr_children, dc); @@ -827,7 +832,7 @@ dc_removechildren(selfref); dr_remove(selfref, dc); dc_rele_byref(parentref); - if ((flags & DC_OP_LOCKPREF) == 0) + if ((flags & DC_LOCKPREF) == 0) dr_unlock(parentref); dc_drop(dc); @@ -843,8 +848,9 @@ dr_assertlock(dc->dc_parentref, MA_OWNED); dc_assertempty(dc); - DCDEBUG("mark negative: %p %s; vp=%p\n", - dc, dc->dc_name, dc->dc_selfref->dr_vnode); + DCDEBUG("mark negative: dc=%p vp=%p ref=%p parentref=%p %s\n", + dc, dc->dc_selfref->dr_vnode, dc->dc_selfref, + dc->dc_parentref, dc->dc_name); dr_updategen(dc->dc_parentref); dc->dc_type = DT_NEGATIVE; @@ -870,25 +876,6 @@ } static void -dc_detachentry(struct dircache *dc) -{ - struct dircache_ref *parentref; - - MPASS(dc->dc_parentref != NULL); - dc_assertlock(dc, MA_OWNED); - dr_assertlock(dc->dc_parentref, MA_OWNED); - - DCDEBUG("detach entry: %p %s\n", dc, dc->dc_name); - parentref = dc->dc_parentref; - dc->dc_parentref = NULL; - RB_REMOVE(dircache_tree, &parentref->dr_children, dc); - dc_invalidate(dc); - - dc_rele_byref(parentref); - dc_droplocked(dc); -} - -static void dc_removechildren(struct dircache_ref *ref) { struct dircache *child; @@ -899,8 +886,7 @@ while(!RB_EMPTY(&ref->dr_children)) { child = RB_MIN(dircache_tree, &ref->dr_children); dc_lock(child); - MPASS(RB_EMPTY(&child->dc_selfref->dr_children)); - dc_removeentry(child, DC_OP_LOCKPREF); + dc_removeentry(child, DC_LOCKPREF); } dr_assertlock(ref, MA_OWNED); @@ -939,7 +925,7 @@ DC_STAT_INC(ds_insert_restart); goto restart; } - dc_removeentry(col, DC_OP_LOCKPREF); + dc_removeentry(col, DC_LOCKPREF); dc_lock(dc); dr_assertlock(parentref, MA_OWNED); goto restart; @@ -961,44 +947,54 @@ dc_purge(struct vnode *vp, dc_filter_t *filter) { struct dircache_ref *parentref, *dr; - struct dircache *dc; + struct dircache *dc, *dctmp; DC_ASSERT_WEAK(vp); restart: dr = dr_get(vp, 0); + DCDEBUG("purge: ref=%p vp=%p filter=%p\n", dr, vp, filter); if (dr == NULL) return; - RB_FOREACH(dc, dircache_tree, &dr->dr_children) { + RB_FOREACH_SAFE(dc, dircache_tree, &dr->dr_children, dctmp) { dr_assertlock(dr, MA_OWNED); dc_lock(dc); if (filter == NULL || filter(dc) != 0) - dc_detachentry(dc); + dc_removeentry(dc, DC_LOCKPREF); else dc_unlock(dc); } while (!LIST_EMPTY(&dr->dr_entries)) { + dr_assertlock(dr, MA_OWNED); dc = LIST_FIRST(&dr->dr_entries); - if (filter != NULL && filter(dc) == 0) - continue; + if (filter != NULL) { + while (dc != NULL && filter(dc) == 0) + dc = LIST_NEXT(dc, dc_reflist); + DCDEBUG("purge: skip by filter: dc=%p\n", dc); + if (dc == NULL) + break; + } + dc_lock(dc); parentref = dc->dc_parentref; if (parentref != NULL) { dc_hold(dc); if (dr_trylock(parentref) == 0) { + dc_unlock(dc); dr_unlock(dr); dr_lock(parentref); + dc_lock(dc); + if (dc->dc_parentref != parentref) { + dr_unlock(parentref); + dc_droplocked(dc); + goto restart; + } } else dr_unlock(dr); - dc_lock(dc); - if (dc->dc_parentref != parentref) { - dr_unlock(parentref); - dc_droplocked(dc); - goto restart; - } dc_removeentry(dc, 0); dc_drop(dc); dr_lock(dr); - } + } else + dc_unlock(dc); } dr_unlock(dr); } @@ -1154,7 +1150,6 @@ dircache_init(struct mount *mp, uint64_t id) { struct dircache_mount *dm; - struct dircache *dc; dm = malloc(sizeof(struct dircache_mount), M_DIRCACHE, M_WAITOK | M_ZERO); @@ -1165,52 +1160,25 @@ if (id != 0) { MPASS((mp->mnt_kern_flag & MNTK_DIRCACHE) != 0); dm->dm_rootref = dr_alloc(dm, NULL, id); - - MPASS(mp->mnt_dircache == NULL); - dc = dc_alloc(DT_ROOT, NULL, 0); - - dr_lock(dm->dm_rootref); - dc_lock(dc); - dp_unused_insert(dc); - dr_add(dm->dm_rootref, dc); - dc_use(dc); - dc_unlock(dc); - dr_unlock(dm->dm_rootref); - DCDEBUG("init: root=%p %jd\n", dc, (intmax_t)id); + DCDEBUG("init: rootref=%p %jd\n", + dm->dm_rootref,(intmax_t)id); } else { MPASS((mp->mnt_kern_flag & MNTK_DIRCACHE) == 0); DCDEBUG("init: weak\n"); } MNT_ILOCK(mp); + MPASS(mp->mnt_dircache == NULL); mp->mnt_dircache = dm; MNT_IUNLOCK(mp); } -void -dircache_uninit(struct mount *mp) +static int +dc_destroyref(struct dircache_ref *dr) { - struct dircache_ref *dr, *childref; - struct dircache *dc, *child; - struct dircache_mount *dm; - int dropped; - - MPASS(mp->mnt_dircache != NULL); - - mtx_lock(&pool.dp_mtx); - dp_invalid_clear(); - mtx_unlock(&pool.dp_mtx); + struct dircache_ref *childref; + struct dircache *child; - MNT_ILOCK(mp); - dm = mp->mnt_dircache; - mp->mnt_dircache = NULL; - MNT_IUNLOCK(mp); - -restart: - dr = dm->dm_rootref; - dr_lock(dr); - DCDEBUG("uninit: rootref=%p\n", dr); - while (dr != NULL && !RB_EMPTY(&dr->dr_children)) { nested: dr_assertlock(dr, MA_OWNED); @@ -1220,7 +1188,7 @@ if (!RB_EMPTY(&childref->dr_children)) { dr_unlock(dr); dr = childref; - DCDEBUG("uninit: go down: ref=%p %s\n", + DCDEBUG("dc_destroyref: go down: ref=%p %s\n", childref, child->dc_name); goto nested; } @@ -1232,37 +1200,76 @@ if (dr != NULL) { if (dr_trylock(dr) == 0) { dr_unlock(childref); - goto restart; + return (-1); } dr_unlock(childref); - DCDEBUG("uninit: go up: ref=%p\n", dr); + DCDEBUG("dc_destroyref: go up: ref=%p\n", dr); } else dr_unlock(childref); } + if (dr != NULL) + dr_unlock(dr); + return (0); +} + +void +dircache_uninit(struct mount *mp) +{ + struct dircache_ref *dr; + struct dircache_mount *dm; + + MPASS(mp->mnt_dircache != NULL); + + mtx_lock(&pool.dp_mtx); + dp_invalid_clear(); + mtx_unlock(&pool.dp_mtx); + + MNT_ILOCK(mp); + dm = mp->mnt_dircache; + mp->mnt_dircache = NULL; + MNT_IUNLOCK(mp); + + dm_lock(dm); + while (!TAILQ_EMPTY(&dm->dm_weakhead)) { + dr = TAILQ_FIRST(&dm->dm_weakhead); + if (dr == dm->dm_negativeref) { + MPASS(TAILQ_NEXT(dr, dr_weaklist) == NULL); + break; + } + dm_unlock(dm); + dr_lock(dr); + dc_destroyref(dr); + dm_lock(dm); + } + dm_unlock(dm); - if (dr == NULL) { + while (1) { dr = dm->dm_rootref; + if (dr == NULL) + break; dr_lock(dr); + DCDEBUG("uninit: rootref=%p\n", dr); + if (dc_destroyref(dr) == 0) + break; } - MPASS(dr == dm->dm_rootref); - MPASS(RB_EMPTY(&dr->dr_children)); - dc = dr_singleentry(dr); - dc_lock(dc); - dr_unlock(dr); - dc_invalidate(dc); - dropped = dc_rele(dc); - MPASS(dropped != 0); + dr = dm->dm_rootref; + if (dr != NULL) { + MPASS(RB_EMPTY(&dr->dr_children)); + MPASS(LIST_EMPTY(&dr->dr_entries)); + } mtx_lock(&pool.dp_mtx); dp_invalid_clear(); mtx_unlock(&pool.dp_mtx); dm_lock(dm); - dr_mntq_remove(dm->dm_rootref); + if (dm->dm_rootref != NULL) + dr_mntq_remove(dm->dm_rootref); dr_mntq_remove(dm->dm_negativeref); dm_unlock(dm); - uma_zfree(dircache_ref_zone, dm->dm_rootref); + if (dm->dm_rootref != NULL) + uma_zfree(dircache_ref_zone, dm->dm_rootref); uma_zfree(dircache_ref_zone, dm->dm_negativeref); MPASS(RB_EMPTY(&dm->dm_idhead)); @@ -1312,18 +1319,23 @@ struct dircache *dc; int error, ltype; + /* FIXME: + * Remove entries for DOT and DOTDOT if (cn_flags & MAKEENTRY) == 0 + */ error = 0; selfref = NULL; - if (cnp->cn_nameptr[0] == '.' && cnp->cn_namelen == 1) + if (cnp->cn_nameptr[0] == '.' && cnp->cn_namelen == 1) { + MPASS((cnp->cn_flags & MAKEENTRY) != 0); return (dircache_lookupdot(dvp, vpp, cnp)); - else if (cnp->cn_nameptr[0] == '.' && cnp->cn_nameptr[1] == '.' && + } else if (cnp->cn_nameptr[0] == '.' && cnp->cn_nameptr[1] == '.' && cnp->cn_namelen == 2) { MPASS((cnp->cn_flags & ISDOTDOT) != 0); - parentref = dr_get(dvp, DC_OP_CREATEREF); + parentref = dr_get(dvp, DC_CREATEREF); if (parentref != NULL) { DCDEBUG("lookup dotdot: dvp=%p\n", dvp); selfref = dr_parentref(parentref); if (selfref != NULL) { + MPASS((cnp->cn_flags & MAKEENTRY) != 0); *vpp = selfref->dr_vnode; if (*vpp != NULL) error = -1; @@ -1332,7 +1344,7 @@ dr_unlock(parentref); } } else { - dc = dc_find(dvp, cnp, DC_OP_LOCKPREF); + dc = dc_find(dvp, cnp, DC_LOCKPREF); if (dc == NULL) { DCDEBUG("lookup: not found: %s; dvp=%p; op=%ld\n", cnp->cn_nameptr, dvp, cnp->cn_nameiop); @@ -1361,8 +1373,13 @@ error, dc, (int)cnp->cn_namelen, cnp->cn_nameptr, dvp, cnp->cn_nameiop); if (dc != NULL) { - dr_unlock(dc->dc_parentref); - dc_unlock(dc); + if (dc->dc_type == DT_WEAK && + (cnp->cn_flags & MAKEENTRY) == 0) { + dc_removeentry(dc, 0); + } else { + dr_unlock(dc->dc_parentref); + dc_unlock(dc); + } } } @@ -1403,17 +1420,17 @@ ndc = dc_alloc(type, cnp->cn_nameptr, cnp->cn_namelen); DCDEBUG("add: %s; vp=%p\n", cnp->cn_nameptr, vp); - parentref = dr_get(dvp, DC_OP_CREATEREF); + parentref = dr_get(dvp, DC_CREATEREF); dc_lock(ndc); rdc = dc_insertentry(parentref, ndc); - dr_assertlock(parentref, MA_NOTOWNED); // XXX + dr_assertlock(parentref, MA_NOTOWNED); if (rdc == ndc) { if (type == DT_NEGATIVE) { MPASS(vp == NULL); selfref = dm_get(dvp)->dm_negativeref; dr_lock(selfref); } else { - selfref = dr_get(vp, DC_OP_CREATEREF); + selfref = dr_get(vp, DC_CREATEREF); dr_updategen(selfref); } MPASS(selfref != NULL); @@ -1461,113 +1478,85 @@ struct vnode *tdvp, struct componentname *tcnp) { struct dircache *dc, *col; - struct dircache_ref *parentref, *fromref; + struct dircache_ref *toref, *fromref; char *namebuf; - int error; DC_ASSERT_STRONG(tdvp); - error = 0; /* FIXME */ namebuf = NULL; if (dc_namebuffits(fcnp->cn_namelen, tcnp->cn_namelen) == 0) { namebuf = dc_allocnamebuf(tcnp->cn_namelen); DC_STAT_INC(ds_rename_realloc); } - dc = dc_find(tdvp, tcnp, DC_OP_LOCKPREF); + dc = dc_find(tdvp, tcnp, DC_LOCKPREF); if (dc != NULL) { - parentref = dc->dc_parentref; - dr_assertlock(parentref, MA_OWNED); - dr_updategen(parentref); - dc_use_byref(parentref); + toref = dc->dc_parentref; + MPASS(toref != NULL); /* FIXME */ + dr_assertlock(toref, MA_OWNED); + dr_updategen(toref); + dc_use_byref(toref); DCDEBUG("rename: remove target: %p %s; parent=%p\n", dc, dc->dc_name, dc->dc_parentref); dc_removeentry(dc, 0); } else { - parentref = dr_get(tdvp, 0); - dc_use_byref(parentref); - dr_unlock(parentref); + toref = dr_get(tdvp, 0); + MPASS(toref != NULL); /* FIXME */ + dr_updategen(toref); + dc_use_byref(toref); + dr_unlock(toref); } if (fdvp == tdvp) { - if (parentref == NULL) { + /* FIXME */ + if (toref == NULL) { if (namebuf != NULL) free(namebuf, M_DIRCACHE); return (ENOENT); } - } else { -#if 0 - if (tcr.dcr_parent == NULL && fcr.dcr_parent == NULL) { - MPASS(dc_getentry(fvp, fcnp) == NULL); - MPASS(tvp == NULL || - dc_getentry(tvp, NULL) == NULL); - return (ENOENT); - } else if (tcr.dcr_parent == NULL) { - fdc = dc_getentry(fvp, fcnp); - if (fdc != NULL) { - dc_marknegative(fdc, fvp); - } else { - MPASS(dc_find(fdvp, fcnp) == 0); - error = ENOENT; - } - dircache_endupdate(&fcr, 0); - return (error); - } else if (fcr.dcr_parent == NULL) { - dircache_partialupdate(&tcr); - return (0); - } -#else - MPASS(parentref != NULL); -#endif } + MPASS(toref != NULL); - dc = dc_find(fdvp, fcnp, DC_OP_LOCKPREF); - MPASS(dc != NULL); - MPASS(dc->dc_parentref != NULL); + dc = dc_find(fdvp, fcnp, DC_LOCKPREF); + KASSERT(dc != NULL, + ("dircache_rename: fvp referenece disappeared: %.*s -> %.*s", + (int)fcnp->cn_namelen, fcnp->cn_nameptr, + (int)tcnp->cn_namelen, tcnp->cn_nameptr)); + fromref = dc->dc_parentref; + MPASS(fromref != NULL); DCDEBUG("rename: rename: %p %s\n", dc, dc->dc_name); - RB_REMOVE(dircache_tree, &dc->dc_parentref->dr_children, dc); + RB_REMOVE(dircache_tree, &fromref->dr_children, dc); + dc->dc_parentref = NULL; dc_setname(dc, tcnp->cn_nameptr, tcnp->cn_namelen, namebuf); dr_updategen(dc->dc_selfref); - dr_updategen(dc->dc_parentref); + dr_updategen(fromref); + dc_rele_byref(fromref); + dr_unlock(fromref); - if (dr_trylock(parentref) == 0) { - fromref = dc->dc_parentref; - dc->dc_parentref = NULL; + if (dr_trylock(toref) == 0) { + DCDEBUG("rename: trylock(toref) failed: dc=%p %s\n", + dc, dc->dc_name); dc_unlock(dc); - dr_unlock(fromref); - dr_lock(parentref); + dr_lock(toref); dc_lock(dc); - // FIXME restart - } else - dr_unlock(dc->dc_parentref); + MPASS(dc->dc_parentref == NULL); + } - dc->dc_parentref = parentref; - dr_updategen(parentref); + dc_assertlock(dc, MA_OWNED); DCDEBUG("rename: insert to tree: %p %s; parent=%p\n", - dc, dc->dc_name, parentref); - col = RB_INSERT(dircache_tree, &parentref->dr_children, dc); + dc, dc->dc_name, toref); + col = RB_INSERT(dircache_tree, &toref->dr_children, dc); + KASSERT(col == NULL, + ("dircache_rename: destination already exists: %.*s -> %.*s", + (int)fcnp->cn_namelen, fcnp->cn_nameptr, + (int)tcnp->cn_namelen, tcnp->cn_nameptr)); MPASS(col == NULL); + dc->dc_parentref = toref; dc_unlock(dc); - - dc_rele_byref(parentref); - dr_unlock(parentref); + dr_unlock(toref); DC_STAT_INC(ds_rename); -#if 0 - if (col != NULL) { - DCDEBUG("rename: insert collision: %p %s; type=%d\n", col, - col->dc_name, col->dc_type); - if (col->dc_type != DT_NEGATIVE) - panic("dircache: rename: invalid entry: %d %s\n", - col->dc_type, col->dc_name); - dc_interlock(fdc, col); - dc_removeentry(col); - dc_lock(fdc); - goto reinsert; - } -#endif - return (0); } @@ -1579,6 +1568,7 @@ struct dircache_ref *dr, key; MPASS(vp->v_type != VNON && vp->v_type != VBAD); + MPASS((vp->v_iflag & VI_DOOMED) == 0); dm = dm_get(vp); dr = NULL; @@ -1637,10 +1627,12 @@ { struct dircache *dc; struct dircache_ref *dr; + int weak, dropped; dr = dr_get(vp, 0); if (dr == NULL) return; + DCDEBUG("reclaimvnode: dr=%p vp=%p\n", dr, vp); VI_LOCK(vp); dr->dr_vnode = NULL; @@ -1654,7 +1646,10 @@ } dc_rele(dc); } - dr_drop(dr); + weak = (dr->dr_id == 0); + dropped = dr_drop(dr); + if (weak != 0) + MPASS(dropped != 0); DC_STAT_INC(ds_reclaimvnode); } @@ -1713,6 +1708,11 @@ DC_ASSERT_WEAK(dvp); + if ((cnp->cn_flags & ISDOTDOT) != 0) { + DCDEBUG("enter: skip dotdot: dvp=%p vp=%p\n", dvp, vp); + return (ENOENT); + } + dircache_allocvnode(dvp, 0); if (vp != NULL) { @@ -1737,7 +1737,7 @@ } -/* FIXME: Remove it. Make cache lookup vfs op. */ +/* FIXME: Should be in vfs_cache.c */ int vfs_dircache_lookup(struct vop_lookup_args *ap) { ==== //depot/projects/soc2010/gk_namecache/sys/modules/tmpfs/Makefile#6 (text+ko) ==== ==== //depot/projects/soc2010/gk_namecache/sys/sys/dircache.h#10 (text+ko) ==== @@ -34,7 +34,7 @@ #include #include -enum dircache_type { DT_INVALID, DT_NEGATIVE, DT_WEAK, DT_STRONG, DT_ROOT }; +enum dircache_type { DT_INVALID, DT_NEGATIVE, DT_WEAK, DT_STRONG }; struct componentname; struct mount;