summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2005-04-13 10:59:09 +0000
committerjeff <jeff@FreeBSD.org>2005-04-13 10:59:09 +0000
commitafab3762a03836a33f6a8bd19afdb3d9559e12ec (patch)
treed93f4bc84645fcd224218d7e1c19b2f6b18a4c6c
parent5642885b84d3a8dfdbf202dfbab02e5c4a93576f (diff)
downloadFreeBSD-src-afab3762a03836a33f6a8bd19afdb3d9559e12ec.zip
FreeBSD-src-afab3762a03836a33f6a8bd19afdb3d9559e12ec.tar.gz
- 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.
-rw-r--r--sys/coda/coda_vnops.c1
-rw-r--r--sys/compat/linux/linux_getcwd.c4
-rw-r--r--sys/fs/cd9660/cd9660_lookup.c5
-rw-r--r--sys/fs/coda/coda_vnops.c1
-rw-r--r--sys/fs/devfs/devfs_vnops.c3
-rw-r--r--sys/fs/hpfs/hpfs_vnops.c6
-rw-r--r--sys/fs/msdosfs/msdosfs_lookup.c5
-rw-r--r--sys/fs/nwfs/nwfs_vnops.c10
-rw-r--r--sys/fs/pseudofs/pseudofs_vnops.c2
-rw-r--r--sys/fs/smbfs/smbfs_vnops.c8
-rw-r--r--sys/fs/udf/udf_vnops.c5
-rw-r--r--sys/fs/unionfs/union_vnops.c11
-rw-r--r--sys/gnu/ext2fs/ext2_lookup.c7
-rw-r--r--sys/gnu/fs/ext2fs/ext2_lookup.c7
-rw-r--r--sys/isofs/cd9660/cd9660_lookup.c5
-rw-r--r--sys/kern/vfs_cache.c8
-rw-r--r--sys/nfs4client/nfs4_vnops.c5
-rw-r--r--sys/nfsclient/nfs_vnops.c5
-rw-r--r--sys/ufs/ufs/ufs_lookup.c5
19 files changed, 39 insertions, 64 deletions
diff --git a/sys/coda/coda_vnops.c b/sys/coda/coda_vnops.c
index c8cf74d..a6f6e1a 100644
--- a/sys/coda/coda_vnops.c
+++ b/sys/coda/coda_vnops.c
@@ -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)) {
diff --git a/sys/compat/linux/linux_getcwd.c b/sys/compat/linux/linux_getcwd.c
index 1dfe6b4..9b810a3 100644
--- a/sys/compat/linux/linux_getcwd.c
+++ b/sys/compat/linux/linux_getcwd.c
@@ -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 @@ unionread:
error = ENOENT;
out:
- vrele(lvp);
+ vput(lvp);
*lvpp = NULL;
free(dirbuf, M_TEMP);
return error;
diff --git a/sys/fs/cd9660/cd9660_lookup.c b/sys/fs/cd9660/cd9660_lookup.c
index 09dbe5f..b89e670 100644
--- a/sys/fs/cd9660/cd9660_lookup.c
+++ b/sys/fs/cd9660/cd9660_lookup.c
@@ -353,10 +353,9 @@ found:
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);
diff --git a/sys/fs/coda/coda_vnops.c b/sys/fs/coda/coda_vnops.c
index c8cf74d..a6f6e1a 100644
--- a/sys/fs/coda/coda_vnops.c
+++ b/sys/fs/coda/coda_vnops.c
@@ -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)) {
diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c
index 90139c2..586aa9b 100644
--- a/sys/fs/devfs/devfs_vnops.c
+++ b/sys/fs/devfs/devfs_vnops.c
@@ -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);
}
diff --git a/sys/fs/hpfs/hpfs_vnops.c b/sys/fs/hpfs/hpfs_vnops.c
index a832827..e099fe7 100644
--- a/sys/fs/hpfs/hpfs_vnops.c
+++ b/sys/fs/hpfs/hpfs_vnops.c
@@ -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 {
diff --git a/sys/fs/msdosfs/msdosfs_lookup.c b/sys/fs/msdosfs/msdosfs_lookup.c
index 70ef2b4..5f3e137 100644
--- a/sys/fs/msdosfs/msdosfs_lookup.c
+++ b/sys/fs/msdosfs/msdosfs_lookup.c
@@ -516,10 +516,9 @@ foundroot:
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 "." */
diff --git a/sys/fs/nwfs/nwfs_vnops.c b/sys/fs/nwfs/nwfs_vnops.c
index e5780d2..90f9c4e 100644
--- a/sys/fs/nwfs/nwfs_vnops.c
+++ b/sys/fs/nwfs/nwfs_vnops.c
@@ -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);
diff --git a/sys/fs/pseudofs/pseudofs_vnops.c b/sys/fs/pseudofs/pseudofs_vnops.c
index 3617cdc..dfae1ef 100644
--- a/sys/fs/pseudofs/pseudofs_vnops.c
+++ b/sys/fs/pseudofs/pseudofs_vnops.c
@@ -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);
diff --git a/sys/fs/smbfs/smbfs_vnops.c b/sys/fs/smbfs/smbfs_vnops.c
index 268e5f8..d741c06 100644
--- a/sys/fs/smbfs/smbfs_vnops.c
+++ b/sys/fs/smbfs/smbfs_vnops.c
@@ -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);
diff --git a/sys/fs/udf/udf_vnops.c b/sys/fs/udf/udf_vnops.c
index c7ff99a..b67bba4 100644
--- a/sys/fs/udf/udf_vnops.c
+++ b/sys/fs/udf/udf_vnops.c
@@ -914,6 +914,7 @@ lookloop:
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 @@ lookloop:
/* 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) {
diff --git a/sys/fs/unionfs/union_vnops.c b/sys/fs/unionfs/union_vnops.c
index ae80503..061696a 100644
--- a/sys/fs/unionfs/union_vnops.c
+++ b/sys/fs/unionfs/union_vnops.c
@@ -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
diff --git a/sys/gnu/ext2fs/ext2_lookup.c b/sys/gnu/ext2fs/ext2_lookup.c
index 2b3481a..0179f97 100644
--- a/sys/gnu/ext2fs/ext2_lookup.c
+++ b/sys/gnu/ext2fs/ext2_lookup.c
@@ -656,11 +656,10 @@ found:
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 "." */
diff --git a/sys/gnu/fs/ext2fs/ext2_lookup.c b/sys/gnu/fs/ext2fs/ext2_lookup.c
index 2b3481a..0179f97 100644
--- a/sys/gnu/fs/ext2fs/ext2_lookup.c
+++ b/sys/gnu/fs/ext2fs/ext2_lookup.c
@@ -656,11 +656,10 @@ found:
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 "." */
diff --git a/sys/isofs/cd9660/cd9660_lookup.c b/sys/isofs/cd9660/cd9660_lookup.c
index 09dbe5f..b89e670 100644
--- a/sys/isofs/cd9660/cd9660_lookup.c
+++ b/sys/isofs/cd9660/cd9660_lookup.c
@@ -353,10 +353,9 @@ found:
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);
diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c
index f911a21..88e32de 100644
--- a/sys/kern/vfs_cache.c
+++ b/sys/kern/vfs_cache.c
@@ -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 @@ success:
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;
}
diff --git a/sys/nfs4client/nfs4_vnops.c b/sys/nfs4client/nfs4_vnops.c
index 50947e0..8a45857 100644
--- a/sys/nfs4client/nfs4_vnops.c
+++ b/sys/nfs4client/nfs4_vnops.c
@@ -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);
diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c
index 0b5109a..8eba072 100644
--- a/sys/nfsclient/nfs_vnops.c
+++ b/sys/nfsclient/nfs_vnops.c
@@ -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);
diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c
index 1efeac4..e4332c1 100644
--- a/sys/ufs/ufs/ufs_lookup.c
+++ b/sys/ufs/ufs/ufs_lookup.c
@@ -560,10 +560,9 @@ found:
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 "." */
OpenPOWER on IntegriCloud