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:
parent
d668f22a0c
commit
18ef8344b4
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=145004
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user