summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_lookup.c
diff options
context:
space:
mode:
authorbp <bp@FreeBSD.org>2000-09-17 07:26:42 +0000
committerbp <bp@FreeBSD.org>2000-09-17 07:26:42 +0000
commit02544af7d4181c17b4280094d740b15516c89895 (patch)
tree6acabed362022c7dc8884295f86728d8a26966b5 /sys/kern/vfs_lookup.c
parente785331769023a37dd8b665cd89d2937f9b417f6 (diff)
downloadFreeBSD-src-02544af7d4181c17b4280094d740b15516c89895.zip
FreeBSD-src-02544af7d4181c17b4280094d740b15516c89895.tar.gz
Add new flag PDIRUNLOCK to the component.cn_flags which should be set by
filesystem lookup() routine if it unlocks parent directory. This flag should be carefully tracked by filesystems if they want to work properly with nullfs and other stacked filesystems. VFS takes advantage of this flag to perform symantically correct usage of vrele() instead of vput() if parent directory already unlocked. If filesystem fails to track this flag then previous codepath in VFS left unchanged. Convert UFS code to set PDIRUNLOCK flag if necessary. Other filesystmes will be changed after some period of testing. Reviewed in general by: mckusick, dillon, adrian Obtained from: NetBSD
Diffstat (limited to 'sys/kern/vfs_lookup.c')
-rw-r--r--sys/kern/vfs_lookup.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
index c9f43d4..4cd4b01 100644
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -418,6 +418,7 @@ dirloop:
unionlookup:
ndp->ni_dvp = dp;
ndp->ni_vp = NULL;
+ cnp->cn_flags &= ~PDIRUNLOCK;
ASSERT_VOP_LOCKED(dp, "lookup");
if ((error = VOP_LOOKUP(dp, &ndp->ni_vp, cnp)) != 0) {
KASSERT(ndp->ni_vp == NULL, ("leaf should be empty"));
@@ -429,7 +430,10 @@ unionlookup:
(dp->v_mount->mnt_flag & MNT_UNION)) {
tdp = dp;
dp = dp->v_mount->mnt_vnodecovered;
- vput(tdp);
+ if (cnp->cn_flags & PDIRUNLOCK)
+ vrele(tdp);
+ else
+ vput(tdp);
VREF(dp);
vn_lock(dp, LK_EXCLUSIVE | LK_RETRY, p);
goto unionlookup;
@@ -557,7 +561,8 @@ nextname:
return (0);
bad2:
- if ((cnp->cn_flags & LOCKPARENT) && *ndp->ni_next == '\0')
+ if ((cnp->cn_flags & (LOCKPARENT | PDIRUNLOCK)) == LOCKPARENT &&
+ *ndp->ni_next == '\0')
VOP_UNLOCK(ndp->ni_dvp, 0, p);
vrele(ndp->ni_dvp);
bad:
OpenPOWER on IntegriCloud