PERFORCE change 182315 for review
Gleb Kurtsou
gk at FreeBSD.org
Thu Aug 12 12:51:27 UTC 2010
http://p4web.freebsd.org/@@182315?ac=10
Change 182315 by gk at 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 <sys/queue.h>
#include <sys/tree.h>
-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;
More information about the p4-projects
mailing list