diff options
author | das <das@FreeBSD.org> | 2005-03-30 03:01:36 +0000 |
---|---|---|
committer | das <das@FreeBSD.org> | 2005-03-30 03:01:36 +0000 |
commit | d3e0f098bea6d2a53ef921866861466d1d128145 (patch) | |
tree | 802fa57c460740973233454fce4d0c5aee42ac88 /sys/kern | |
parent | 0fa243e9cdc07f80152b188d9aceb4d80c8c30c0 (diff) | |
download | FreeBSD-src-d3e0f098bea6d2a53ef921866861466d1d128145.zip FreeBSD-src-d3e0f098bea6d2a53ef921866861466d1d128145.tar.gz |
Eliminate v_id and v_ddid. The name cache now holds references to
vnodes whose names it caches, so we no longer need a `generation
number' to tell us if a referenced vnode is invalid. Replace the use
of the parent's v_id in the hash function with the address of the
parent vnode.
Tested by: Peter Holm
Glanced at by: jeff, phk
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/vfs_cache.c | 46 | ||||
-rw-r--r-- | sys/kern/vfs_subr.c | 3 |
2 files changed, 11 insertions, 38 deletions
diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c index 92614f7..f911a21 100644 --- a/sys/kern/vfs_cache.c +++ b/sys/kern/vfs_cache.c @@ -361,9 +361,8 @@ retry: } if (cnp->cn_namelen == 2 && cnp->cn_nameptr[1] == '.') { dotdothits++; - if (dvp->v_dd->v_id != dvp->v_ddid || + if (dvp->v_dd == NULL || (cnp->cn_flags & MAKEENTRY) == 0) { - dvp->v_ddid = 0; CACHE_UNLOCK(); return (0); } @@ -373,7 +372,7 @@ retry: } hash = fnv_32_buf(cnp->cn_nameptr, cnp->cn_namelen, FNV1_32_INIT); - hash = fnv_32_buf(&dvp->v_id, sizeof(dvp->v_id), hash); + hash = fnv_32_buf(&dvp, sizeof(dvp), hash); LIST_FOREACH(ncp, (NCHHASH(hash)), nc_hash) { numchecks++; if (ncp->nc_dvp == dvp && ncp->nc_nlen == cnp->cn_namelen && @@ -481,13 +480,7 @@ cache_enter(dvp, vp, cnp) return; } if (cnp->cn_namelen == 2 && cnp->cn_nameptr[1] == '.') { - if (vp) { - dvp->v_dd = vp; - dvp->v_ddid = vp->v_id; - } else { - dvp->v_dd = dvp; - dvp->v_ddid = 0; - } + dvp->v_dd = vp; return; } } @@ -502,7 +495,8 @@ cache_enter(dvp, vp, cnp) ncp->nc_flag = cnp->cn_flags & ISWHITEOUT ? NCF_WHITE : 0; } else if (vp->v_type == VDIR) { vp->v_dd = dvp; - vp->v_ddid = dvp->v_id; + } else { + vp->v_dd = NULL; } /* @@ -515,7 +509,7 @@ cache_enter(dvp, vp, cnp) len = ncp->nc_nlen = cnp->cn_namelen; hash = fnv_32_buf(cnp->cn_nameptr, len, FNV1_32_INIT); bcopy(cnp->cn_nameptr, ncp->nc_name, len); - hash = fnv_32_buf(&dvp->v_id, sizeof(dvp->v_id), hash); + hash = fnv_32_buf(&dvp, sizeof(dvp), hash); ncpp = NCHHASH(hash); LIST_INSERT_HEAD(ncpp, ncp, nc_hash); if (LIST_EMPTY(&dvp->v_cache_src)) { @@ -565,25 +559,12 @@ SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_SECOND, nchinit, NULL) /* * Invalidate all entries to a particular vnode. - * - * Remove all entries in the namecache relating to this vnode and - * change the v_id. We take the v_id from a global counter, since - * it becomes a handy sequence number in crash-dumps that way. - * No valid vnode will ever have (v_id == 0). - * - * XXX: Only time and the size of v_id prevents this from failing: - * XXX: In theory we should hunt down all (struct vnode*, v_id) - * XXX: soft references and nuke them, at least on the global - * XXX: v_id wraparound. The period of resistance can be extended - * XXX: by incrementing each vnodes v_id individually instead of - * XXX: using the global v_id. */ void cache_purge(vp) struct vnode *vp; { struct namecache *ncp; - static u_long nextid; CACHE_LOCK(); while (!LIST_EMPTY(&vp->v_cache_src)) { @@ -594,20 +575,13 @@ cache_purge(vp) * We must reset v_dd of any children so they don't * continue to point to us. */ - if ((cvp = ncp->nc_vp) && cvp->v_dd == vp) { - cvp->v_dd = cvp; - cvp->v_ddid = 0; - } + if ((cvp = ncp->nc_vp) && cvp->v_dd == vp) + cvp->v_dd = NULL; cache_zap(ncp); } while (!TAILQ_EMPTY(&vp->v_cache_dst)) cache_zap(TAILQ_FIRST(&vp->v_cache_dst)); - do - nextid++; - while (nextid == vp->v_id || !nextid); - vp->v_id = nextid; - vp->v_dd = vp; - vp->v_ddid = 0; + vp->v_dd = NULL; CACHE_UNLOCK(); } @@ -843,7 +817,7 @@ vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir, vp = vp->v_mount->mnt_vnodecovered; continue; } - if (vp->v_dd->v_id != vp->v_ddid) { + if (vp->v_dd == NULL) { numfullpathfail1++; error = ENOTDIR; break; diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 97165dc..d3e5ee3 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -847,7 +847,6 @@ getnewvnode(tag, mp, vops, vpp) */ LIST_INIT(&vp->v_cache_src); TAILQ_INIT(&vp->v_cache_dst); - cache_purge(vp); /* Sets up v_id. */ /* * Finalize various vnode identity bits. */ @@ -2564,11 +2563,11 @@ sysctl_vnode(SYSCTL_HANDLER_ARGS) vref(vp); xvn[n].xv_size = sizeof *xvn; xvn[n].xv_vnode = vp; + xvn[n].xv_id = 0; /* XXX compat */ #define XV_COPY(field) xvn[n].xv_##field = vp->v_##field XV_COPY(usecount); XV_COPY(writecount); XV_COPY(holdcnt); - XV_COPY(id); XV_COPY(mount); XV_COPY(numoutput); XV_COPY(type); |