- Change all filesystems and vfs_cache to relock the dvp once the child is
locked in the ISDOTDOT case. Se vfs_lookup.c r1.79 for details. Sponsored by: Isilon Systems, Inc.
This commit is contained in:
parent
374df05fd3
commit
4585e3ac5a
@ -1010,6 +1010,7 @@ coda_lookup(struct vop_lookup_args *ap)
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
vn_lock(dvp, LK_RETRY|LK_EXCLUSIVE, td);
|
||||
} else {
|
||||
/* The parent is locked, and may be the same as the child */
|
||||
if (*ap->a_vpp && (*ap->a_vpp != dvp)) {
|
||||
|
@ -185,7 +185,7 @@ linux_getcwd_scandir(lvpp, uvpp, bpp, bufp, td)
|
||||
|
||||
/* If we don't care about the pathname, we're done */
|
||||
if (bufp == NULL) {
|
||||
vrele(lvp);
|
||||
vput(lvp);
|
||||
*lvpp = NULL;
|
||||
return 0;
|
||||
}
|
||||
@ -281,7 +281,7 @@ linux_getcwd_scandir(lvpp, uvpp, bpp, bufp, td)
|
||||
error = ENOENT;
|
||||
|
||||
out:
|
||||
vrele(lvp);
|
||||
vput(lvp);
|
||||
*lvpp = NULL;
|
||||
free(dirbuf, M_TEMP);
|
||||
return error;
|
||||
|
@ -353,10 +353,9 @@ cd9660_lookup(ap)
|
||||
LK_EXCLUSIVE, &tdp,
|
||||
dp->i_ino != ino, ep);
|
||||
brelse(bp);
|
||||
if (error) {
|
||||
vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
*vpp = tdp;
|
||||
} else if (dp->i_number == dp->i_ino) {
|
||||
brelse(bp);
|
||||
|
@ -1010,6 +1010,7 @@ coda_lookup(struct vop_lookup_args *ap)
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
vn_lock(dvp, LK_RETRY|LK_EXCLUSIVE, td);
|
||||
} else {
|
||||
/* The parent is locked, and may be the same as the child */
|
||||
if (*ap->a_vpp && (*ap->a_vpp != dvp)) {
|
||||
|
@ -618,8 +618,7 @@ devfs_lookupx(ap)
|
||||
de = TAILQ_NEXT(de, de_list); /* ".." */
|
||||
de = de->de_dir;
|
||||
error = devfs_allocv(de, dvp->v_mount, vpp, td);
|
||||
if (error)
|
||||
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -1060,11 +1060,9 @@ hpfs_lookup(ap)
|
||||
VOP_UNLOCK(dvp,0,cnp->cn_thread);
|
||||
error = VFS_VGET(hpmp->hpm_mp,
|
||||
dhp->h_fn.fn_parent, LK_EXCLUSIVE, ap->a_vpp);
|
||||
if (error) {
|
||||
vn_lock(dvp, LK_EXCLUSIVE|LK_RETRY,
|
||||
cnp->cn_thread);
|
||||
vn_lock(dvp, LK_EXCLUSIVE|LK_RETRY, cnp->cn_thread);
|
||||
if (error)
|
||||
return(error);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
} else {
|
||||
|
@ -516,10 +516,9 @@ msdosfs_lookup(ap)
|
||||
if (flags & ISDOTDOT) {
|
||||
VOP_UNLOCK(pdp, 0, td);
|
||||
error = deget(pmp, cluster, blkoff, &tdp);
|
||||
if (error) {
|
||||
vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
*vpp = DETOV(tdp);
|
||||
} else if (dp->de_StartCluster == scn && isadir) {
|
||||
VREF(vdp); /* we want ourself, ie "." */
|
||||
|
@ -883,8 +883,7 @@ printf("dvp %d:%d:%d\n", (int)mp, (int)dvp->v_vflag & VV_ROOT, (int)flags & ISDO
|
||||
} else if (flags & ISDOTDOT) {
|
||||
VOP_UNLOCK(dvp, 0, td); /* unlock parent */
|
||||
error = vget(vp, LK_EXCLUSIVE, td);
|
||||
if (error)
|
||||
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
} else
|
||||
error = vget(vp, LK_EXCLUSIVE, td);
|
||||
if (!error) {
|
||||
@ -901,8 +900,6 @@ printf("dvp %d:%d:%d\n", (int)mp, (int)dvp->v_vflag & VV_ROOT, (int)flags & ISDO
|
||||
vput(vp);
|
||||
else
|
||||
vrele(vp);
|
||||
if (flags & ISDOTDOT)
|
||||
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
}
|
||||
vdrop(vp);
|
||||
*vpp = NULLVP;
|
||||
@ -978,10 +975,9 @@ printf("dvp %d:%d:%d\n", (int)mp, (int)dvp->v_vflag & VV_ROOT, (int)flags & ISDO
|
||||
if (flags & ISDOTDOT) {
|
||||
VOP_UNLOCK(dvp, 0, td); /* race to get the inode */
|
||||
error = nwfs_nget(mp, fid, NULL, NULL, &vp);
|
||||
if (error) {
|
||||
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
*vpp = vp;
|
||||
} else if (NWCMPF(&dnp->n_fid, &fid)) {
|
||||
vref(dvp);
|
||||
|
@ -413,6 +413,8 @@ pfs_lookup(struct vop_cachedlookup_args *va)
|
||||
if (error)
|
||||
goto failed;
|
||||
|
||||
if (cnp->cn_flags & ISDOTDOT)
|
||||
vn_lock(vn, LK_EXCLUSIVE|LK_RETRY, cnp->cn_thread);
|
||||
if (cnp->cn_flags & MAKEENTRY)
|
||||
cache_enter(vn, *vpp, cnp);
|
||||
PFS_RETURN (0);
|
||||
|
@ -1155,9 +1155,6 @@ smbfs_lookup(ap)
|
||||
vput(vp);
|
||||
else
|
||||
vrele(vp);
|
||||
if (flags & ISDOTDOT)
|
||||
if (vn_lock(dvp, LK_EXCLUSIVE, td))
|
||||
panic("smbfs_lookup: Can't relock directory.");
|
||||
*vpp = NULLVP;
|
||||
}
|
||||
/*
|
||||
@ -1229,10 +1226,9 @@ smbfs_lookup(ap)
|
||||
if (flags & ISDOTDOT) {
|
||||
VOP_UNLOCK(dvp, 0, td);
|
||||
error = smbfs_nget(mp, dvp, name, nmlen, NULL, &vp);
|
||||
if (error) {
|
||||
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
*vpp = vp;
|
||||
} else if (isdot) {
|
||||
vref(dvp);
|
||||
|
@ -914,6 +914,7 @@ udf_lookup(struct vop_cachedlookup_args *a)
|
||||
if (flags & ISDOTDOT)
|
||||
VOP_UNLOCK(dvp, 0, a->a_cnp->cn_thread);
|
||||
error = udf_vget(udfmp->im_mountp, id, LK_EXCLUSIVE, &tdp);
|
||||
vn_lock(dvp, LK_EXCLUSIVE|LK_RETRY, a->a_cnp->cn_thread);
|
||||
if (!error) {
|
||||
/*
|
||||
* Remember where this entry was if it's the final
|
||||
@ -927,9 +928,7 @@ udf_lookup(struct vop_cachedlookup_args *a)
|
||||
/* Put this entry in the cache */
|
||||
if (flags & MAKEENTRY)
|
||||
cache_enter(dvp, *vpp, a->a_cnp);
|
||||
} else if (flags & ISDOTDOT)
|
||||
vn_lock(dvp, LK_EXCLUSIVE|LK_RETRY,
|
||||
a->a_cnp->cn_thread);
|
||||
}
|
||||
} else {
|
||||
/* Name wasn't found on this pass. Do another pass? */
|
||||
if (numdirpasses == 2) {
|
||||
|
@ -226,19 +226,8 @@ union_lookup1(udvp, pdvp, vpp, cnp)
|
||||
*vpp = NULL;
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* The parent directory will have been unlocked, unless this is a
|
||||
* dotdot lookup or if dvp == tdvp (tdvp must be locked).
|
||||
*
|
||||
* We want our dvp to remain locked and ref'd. We also want tdvp
|
||||
* to remain locked and ref'd.
|
||||
*/
|
||||
UDEBUG(("parentdir %p result %p flag %lx\n", dvp, tdvp, cnp->cn_flags));
|
||||
|
||||
if (dvp != tdvp && (cnp->cn_flags & ISDOTDOT))
|
||||
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
|
||||
/*
|
||||
* Lastly check if the current node is a mount point in
|
||||
* which case walk up the mount hierarchy making sure not to
|
||||
|
@ -656,11 +656,10 @@ ext2_lookup(ap)
|
||||
pdp = vdp;
|
||||
if (flags & ISDOTDOT) {
|
||||
VOP_UNLOCK(pdp, 0, td); /* race to get the inode */
|
||||
if ((error = VFS_VGET(vdp->v_mount, dp->i_ino, LK_EXCLUSIVE,
|
||||
&tdp)) != 0) {
|
||||
vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
error = VFS_VGET(vdp->v_mount, dp->i_ino, LK_EXCLUSIVE, &tdp);
|
||||
vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
}
|
||||
*vpp = tdp;
|
||||
} else if (dp->i_number == dp->i_ino) {
|
||||
VREF(vdp); /* we want ourself, ie "." */
|
||||
|
@ -656,11 +656,10 @@ ext2_lookup(ap)
|
||||
pdp = vdp;
|
||||
if (flags & ISDOTDOT) {
|
||||
VOP_UNLOCK(pdp, 0, td); /* race to get the inode */
|
||||
if ((error = VFS_VGET(vdp->v_mount, dp->i_ino, LK_EXCLUSIVE,
|
||||
&tdp)) != 0) {
|
||||
vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
error = VFS_VGET(vdp->v_mount, dp->i_ino, LK_EXCLUSIVE, &tdp);
|
||||
vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
}
|
||||
*vpp = tdp;
|
||||
} else if (dp->i_number == dp->i_ino) {
|
||||
VREF(vdp); /* we want ourself, ie "." */
|
||||
|
@ -353,10 +353,9 @@ cd9660_lookup(ap)
|
||||
LK_EXCLUSIVE, &tdp,
|
||||
dp->i_ino != ino, ep);
|
||||
brelse(bp);
|
||||
if (error) {
|
||||
vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
*vpp = tdp;
|
||||
} else if (dp->i_number == dp->i_ino) {
|
||||
brelse(bp);
|
||||
|
@ -344,6 +344,7 @@ cache_lookup(dvp, vpp, cnp)
|
||||
{
|
||||
struct namecache *ncp;
|
||||
u_int32_t hash;
|
||||
int error;
|
||||
|
||||
if (!doingcache) {
|
||||
cnp->cn_flags &= ~MAKEENTRY;
|
||||
@ -447,9 +448,10 @@ cache_lookup(dvp, vpp, cnp)
|
||||
VOP_UNLOCK(dvp, 0, cnp->cn_thread);
|
||||
VI_LOCK(*vpp);
|
||||
CACHE_UNLOCK();
|
||||
if (vget(*vpp, cnp->cn_lkflags | LK_INTERLOCK, cnp->cn_thread)) {
|
||||
if (cnp->cn_flags & ISDOTDOT)
|
||||
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, cnp->cn_thread);
|
||||
error = vget(*vpp, cnp->cn_lkflags | LK_INTERLOCK, cnp->cn_thread);
|
||||
if (cnp->cn_flags & ISDOTDOT)
|
||||
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, cnp->cn_thread);
|
||||
if (error) {
|
||||
*vpp = NULL;
|
||||
goto retry;
|
||||
}
|
||||
|
@ -1050,10 +1050,9 @@ nfs4_lookup(struct vop_lookup_args *ap)
|
||||
VOP_UNLOCK(dvp, 0, td);
|
||||
|
||||
error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
|
||||
if (error) {
|
||||
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
newvp = NFSTOV(np);
|
||||
|
||||
nfs4_vnop_loadattrcache(newvp, &ga.fa, NULL);
|
||||
|
@ -860,10 +860,9 @@ nfs_lookup(struct vop_lookup_args *ap)
|
||||
if (flags & ISDOTDOT) {
|
||||
VOP_UNLOCK(dvp, 0, td);
|
||||
error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
|
||||
if (error) {
|
||||
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
newvp = NFSTOV(np);
|
||||
} else if (NFS_CMPFH(np, fhp, fhsize)) {
|
||||
VREF(dvp);
|
||||
|
@ -560,10 +560,9 @@ ufs_lookup(ap)
|
||||
VOP_UNLOCK(pdp, 0, td); /* race to get the inode */
|
||||
error = VFS_VGET(pdp->v_mount, dp->i_ino,
|
||||
cnp->cn_lkflags, &tdp);
|
||||
if (error) {
|
||||
vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
*vpp = tdp;
|
||||
} else if (dp->i_number == dp->i_ino) {
|
||||
VREF(vdp); /* we want ourself, ie "." */
|
||||
|
Loading…
Reference in New Issue
Block a user