summaryrefslogtreecommitdiffstats
path: root/sys/ufs/ufs
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/ufs/ufs
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/ufs/ufs')
-rw-r--r--sys/ufs/ufs/ufs_lookup.c43
1 files changed, 30 insertions, 13 deletions
diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c
index ee28d48..cddd025 100644
--- a/sys/ufs/ufs/ufs_lookup.c
+++ b/sys/ufs/ufs/ufs_lookup.c
@@ -154,6 +154,7 @@ ufs_lookup(ap)
bp = NULL;
slotoffset = -1;
+ cnp->cn_flags &= ~PDIRUNLOCK;
/*
* XXX there was a soft-update diff about this I couldn't merge.
* I think this was the equiv.
@@ -395,8 +396,10 @@ notfound:
* information cannot be used.
*/
cnp->cn_flags |= SAVENAME;
- if (!lockparent)
+ if (!lockparent) {
VOP_UNLOCK(vdp, 0, p);
+ cnp->cn_flags |= PDIRUNLOCK;
+ }
return (EJUSTRETURN);
}
/*
@@ -460,8 +463,10 @@ found:
if (flags & ISDOTDOT)
VOP_UNLOCK(vdp, 0, p); /* race to get the inode */
error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp);
- if (flags & ISDOTDOT)
- vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY, p);
+ if (flags & ISDOTDOT) {
+ if (vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY, p) != 0)
+ cnp->cn_flags |= PDIRUNLOCK;
+ }
if (error)
return (error);
/*
@@ -478,8 +483,10 @@ found:
return (EPERM);
}
*vpp = tdp;
- if (!lockparent)
+ if (!lockparent) {
VOP_UNLOCK(vdp, 0, p);
+ cnp->cn_flags |= PDIRUNLOCK;
+ }
return (0);
}
@@ -501,14 +508,18 @@ found:
if (flags & ISDOTDOT)
VOP_UNLOCK(vdp, 0, p); /* race to get the inode */
error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp);
- if (flags & ISDOTDOT)
- vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY, p);
+ if (flags & ISDOTDOT) {
+ if (vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY, p) != 0)
+ cnp->cn_flags |= PDIRUNLOCK;
+ }
if (error)
return (error);
*vpp = tdp;
cnp->cn_flags |= SAVENAME;
- if (!lockparent)
+ if (!lockparent) {
VOP_UNLOCK(vdp, 0, p);
+ cnp->cn_flags |= PDIRUNLOCK;
+ }
return (0);
}
@@ -534,14 +545,18 @@ found:
pdp = vdp;
if (flags & ISDOTDOT) {
VOP_UNLOCK(pdp, 0, p); /* race to get the inode */
+ cnp->cn_flags |= PDIRUNLOCK;
if ((error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp)) != 0) {
- vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, p);
+ if (vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, p) == 0)
+ cnp->cn_flags &= ~PDIRUNLOCK;
return (error);
}
- if (lockparent && (flags & ISLASTCN) &&
- (error = vn_lock(pdp, LK_EXCLUSIVE, p))) {
- vput(tdp);
- return (error);
+ if (lockparent && (flags & ISLASTCN)) {
+ if ((error = vn_lock(pdp, LK_EXCLUSIVE, p)) != 0) {
+ vput(tdp);
+ return (error);
+ }
+ cnp->cn_flags &= ~PDIRUNLOCK;
}
*vpp = tdp;
} else if (dp->i_number == dp->i_ino) {
@@ -551,8 +566,10 @@ found:
error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp);
if (error)
return (error);
- if (!lockparent || !(flags & ISLASTCN))
+ if (!lockparent || !(flags & ISLASTCN)) {
VOP_UNLOCK(pdp, 0, p);
+ cnp->cn_flags |= PDIRUNLOCK;
+ }
*vpp = tdp;
}
OpenPOWER on IntegriCloud