1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-14 10:09:48 +00:00

- Further simplify lookup; Force all filesystems to relock in the DOTDOT

case.  There are bugs in some which didn't unlock in the ISDOTDOT case
   to begin with that need to be addressed seperately.  This simplifies
   things anyway.
 - Fix relookup() to prevent it from vrele()'ing the dvp while the vp
   is locked.  Catch up to other lookup changes.

Sponsored by:	Isilon Systems, Inc.
Reported by:	Peter Wemm
This commit is contained in:
Jeff Roberson 2005-04-13 10:57:13 +00:00
parent d668f22a0c
commit 18ef8344b4
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=145004

View File

@ -591,12 +591,6 @@ lookup(ndp)
#ifdef NAMEI_DIAGNOSTIC
printf("found\n");
#endif
/*
* In the DOTDOT case dp is unlocked, we relock it here even if we
* may not need it to simplify the code below.
*/
if (cnp->cn_flags & ISDOTDOT)
vn_lock(dp, LK_EXCLUSIVE | LK_RETRY, td);
/*
* Take into account any additional components consumed by
* the underlying filesystem.
@ -746,6 +740,7 @@ relookup(dvp, vpp, cnp)
* Setup: break out flag bits into variables.
*/
wantparent = cnp->cn_flags & (LOCKPARENT|WANTPARENT);
KASSERT(wantparent, ("relookup: parent not wanted."));
rdonly = cnp->cn_flags & RDONLY;
cnp->cn_flags &= ~ISSYMLINK;
dp = dvp;
@ -826,46 +821,44 @@ relookup(dvp, vpp, cnp)
*/
return (0);
}
/*
* In the DOTDOT case dp is unlocked, we may have to relock it if
* LOCKPARENT is set. Otherwise, unlock the parent.
*/
if ((cnp->cn_flags & (ISDOTDOT | LOCKPARENT)) ==
(ISDOTDOT | LOCKPARENT))
vn_lock(dp, LK_EXCLUSIVE | LK_RETRY, td);
else if ((cnp->cn_flags & (ISDOTDOT | LOCKPARENT)) == 0 && dp != *vpp)
VOP_UNLOCK(dp, 0, td);
dp = *vpp;
/*
* Check for symbolic link
*/
KASSERT(dp->v_type != VLNK || !(cnp->cn_flags & FOLLOW),
("relookup: symlink found.\n"));
/*
* Disallow directory write attempts on read-only filesystems.
*/
if (rdonly &&
(cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) {
printf("this is it?\n");
if (dvp == dp)
vrele(dvp);
else
vput(dvp);
error = EROFS;
goto bad2;
goto bad;
}
/*
* Set the parent lock/ref state to the requested state.
*/
if ((cnp->cn_flags & LOCKPARENT) == 0 && dvp != dp) {
if (wantparent)
VOP_UNLOCK(dvp, 0, td);
else
vput(dvp);
} else if (!wantparent)
vrele(dvp);
/*
* Check for symbolic link
*/
KASSERT(dp->v_type != VLNK || !(cnp->cn_flags & FOLLOW),
("relookup: symlink found.\n"));
/* ASSERT(dvp == ndp->ni_startdir) */
if (cnp->cn_flags & SAVESTART)
VREF(dvp);
if (!wantparent)
vrele(dvp);
if ((cnp->cn_flags & LOCKLEAF) == 0)
VOP_UNLOCK(dp, 0, td);
return (0);
bad2:
if (cnp->cn_flags & LOCKPARENT)
VOP_UNLOCK(dvp, 0, td);
vrele(dvp);
bad:
vput(dp);
*vpp = NULL;