1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-12 09:58:36 +00:00

- Fix a leaked reference to a vnode via v_dd. We rely on cache_purge() and

cache_zap() to clear the v_dd pointers when a directory vnode is forcibly
   discarded.  For this to work, all vnodes with v_dd pointers to a directory
   must also have name cache entries linked via v_cache_dst to that dvp
   otherwise we could not find them at cache_purge() time.  The following
   code snipit could break this guarantee by unlinking a directory before
   fetching it's dotdot.  The dotdot lookup would initialize the v_dd field
   of the unlinked directory which could never be cleared.  To fix this
   we don't initialize v_dd for orphaned vnodes.
        printf("rmdir: %d\n", rmdir("../foo")); /* foo is cwd */
        printf("chdir: %d\n", chdir(".."));
        printf("%s\n", getwd(NULL));

Sponsored by:	Isilon Systems, Inc.
Discovered by:	kkenn
Approved by:	re (blanket vfs)
This commit is contained in:
Jeff Roberson 2005-06-17 01:05:13 +00:00
parent 482b893365
commit 32b6dcd8a4
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=147450

View File

@ -493,8 +493,18 @@ cache_enter(dvp, vp, cnp)
if (cnp->cn_namelen == 1) {
return;
}
/*
* For dotdot lookups only cache the v_dd pointer if the
* directory has a link back to its parent via v_cache_dst.
* Without this an unlinked directory would keep a soft
* reference to its parent which could not be NULLd at
* cache_purge() time.
*/
if (cnp->cn_namelen == 2 && cnp->cn_nameptr[1] == '.') {
dvp->v_dd = vp;
CACHE_LOCK();
if (!TAILQ_EMPTY(&dvp->v_cache_dst))
dvp->v_dd = vp;
CACHE_UNLOCK();
return;
}
}