summaryrefslogtreecommitdiff
path: root/sys/msdosfs
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2003-01-31 17:37:51 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2003-01-31 17:37:51 +0000
commit1b0b18abe62afb1a61733a6f5891a98bfbea81ec (patch)
tree29dc896fd65580ea85012ef60aaf813858629e3f /sys/msdosfs
parent2bccdd51809becfe909c271f5fef4d380c663209 (diff)
File system locking fixups, mostly from NetBSD:
- cache_lookup move common code from various fs's here always return with vnode and parent locked adjust return codes - PDIRUNLOCK - new flag set if lookup couldn't lock parent vnode - kernfs and procfs lock vnode in get_root don't unlock (again) in kernfs_freevp fix memory leak in procfs From tedu@stanford.edu deraadt@ and various other ok
Diffstat (limited to 'sys/msdosfs')
-rw-r--r--sys/msdosfs/msdosfs_lookup.c88
1 files changed, 27 insertions, 61 deletions
diff --git a/sys/msdosfs/msdosfs_lookup.c b/sys/msdosfs/msdosfs_lookup.c
index 1a6baa0233b..1778a741972 100644
--- a/sys/msdosfs/msdosfs_lookup.c
+++ b/sys/msdosfs/msdosfs_lookup.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: msdosfs_lookup.c,v 1.11 1999/02/19 17:26:17 art Exp $ */
+/* $OpenBSD: msdosfs_lookup.c,v 1.12 2003/01/31 17:37:50 art Exp $ */
/* $NetBSD: msdosfs_lookup.c,v 1.34 1997/10/18 22:12:27 ws Exp $ */
/*-
@@ -110,12 +110,15 @@ msdosfs_lookup(v)
struct buf *bp = 0;
struct direntry *dep;
u_char dosfilename[12];
- int flags = cnp->cn_flags;
+ int flags;
int nameiop = cnp->cn_nameiop;
int wincnt = 1;
int chksum = -1;
int olddos = 1;
-
+
+ cnp->cn_flags &= ~PDIRUNLOCK; /* XXX why this ?? */
+ flags = cnp->cn_flags;
+
#ifdef MSDOSFS_DEBUG
printf("msdosfs_lookup(): looking for %s\n", cnp->cn_nameptr);
#endif
@@ -144,56 +147,8 @@ msdosfs_lookup(v)
* check the name cache to see if the directory/name pair
* we are looking for is known already.
*/
- if ((error = cache_lookup(vdp, vpp, cnp)) != 0) {
- int vpid;
-
- if (error == ENOENT)
- return (error);
- /*
- * Get the next vnode in the path.
- * See comment below starting `Step through' for
- * an explaination of the locking protocol.
- */
- pdp = vdp;
- dp = VTODE(*vpp);
- vdp = *vpp;
- vpid = vdp->v_id;
- if (pdp == vdp) { /* lookup on "." */
- VREF(vdp);
- error = 0;
- } else if (flags & ISDOTDOT) {
- VOP_UNLOCK(pdp, 0, p);
- error = vget(vdp, LK_EXCLUSIVE, p);
- if (!error && lockparent && (flags & ISLASTCN))
- error =
- vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, p);
- } else {
- error = vget(vdp, LK_EXCLUSIVE, p);
- if (!lockparent || error || !(flags & ISLASTCN))
- VOP_UNLOCK(pdp, 0, p);
- }
- /*
- * Check that the capability number did not change
- * while we were waiting for the lock.
- */
- if (!error) {
- if (vpid == vdp->v_id) {
-#ifdef MSDOSFS_DEBUG
- printf("msdosfs_lookup(): cache hit, vnode %08x, file %s\n",
- vdp, dp->de_Name);
-#endif
- return (0);
- }
- vput(vdp);
- if (lockparent && pdp != vdp && (flags & ISLASTCN))
- VOP_UNLOCK(pdp, 0, p);
- }
- if ((error = vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, p)) != 0)
- return (error);
- vdp = pdp;
- dp = VTODE(vdp);
- *vpp = NULL;
- }
+ if ((error = cache_lookup(vdp, vpp, cnp)) >= 0)
+ return (error);
/*
* If they are going after the . or .. entry in the root directory,
@@ -415,8 +370,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);
}
/*
@@ -504,8 +461,10 @@ foundroot:;
if ((error = deget(pmp, cluster, blkoff, &tdp)) != 0)
return (error);
*vpp = DETOV(tdp);
- if (!lockparent)
+ if (!lockparent) {
VOP_UNLOCK(vdp, 0, p);
+ cnp->cn_flags |= PDIRUNLOCK;
+ }
return (0);
}
@@ -562,14 +521,19 @@ foundroot:;
pdp = vdp;
if (flags & ISDOTDOT) {
VOP_UNLOCK(pdp, 0, p); /* race to get the inode */
+ cnp->cn_flags |= PDIRUNLOCK;
if ((error = deget(pmp, cluster, blkoff, &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 | LK_RETRY, p))) {
- vput(DETOV(tdp));
- return (error);
+ if (lockparent && (flags & ISLASTCN)) {
+ if ((error = vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY,
+ p))) {
+ vput(DETOV(tdp));
+ return (error);
+ }
+ cnp->cn_flags &= ~PDIRUNLOCK;
}
*vpp = DETOV(tdp);
} else if (dp->de_StartCluster == scn && isadir) {
@@ -578,8 +542,10 @@ foundroot:;
} else {
if ((error = deget(pmp, cluster, blkoff, &tdp)) != 0)
return (error);
- if (!lockparent || !(flags & ISLASTCN))
+ if (!lockparent || !(flags & ISLASTCN)) {
VOP_UNLOCK(pdp, 0, p);
+ cnp->cn_flags |= PDIRUNLOCK;
+ }
*vpp = DETOV(tdp);
}