diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2003-01-31 17:37:51 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2003-01-31 17:37:51 +0000 |
commit | 1b0b18abe62afb1a61733a6f5891a98bfbea81ec (patch) | |
tree | 29dc896fd65580ea85012ef60aaf813858629e3f /sys/ufs/ext2fs/ext2fs_lookup.c | |
parent | 2bccdd51809becfe909c271f5fef4d380c663209 (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/ufs/ext2fs/ext2fs_lookup.c')
-rw-r--r-- | sys/ufs/ext2fs/ext2fs_lookup.c | 78 |
1 files changed, 24 insertions, 54 deletions
diff --git a/sys/ufs/ext2fs/ext2fs_lookup.c b/sys/ufs/ext2fs/ext2fs_lookup.c index b5c21c3957e..cf22aa06846 100644 --- a/sys/ufs/ext2fs/ext2fs_lookup.c +++ b/sys/ufs/ext2fs/ext2fs_lookup.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ext2fs_lookup.c,v 1.14 2002/10/12 01:09:45 krw Exp $ */ +/* $OpenBSD: ext2fs_lookup.c,v 1.15 2003/01/31 17:37:50 art Exp $ */ /* $NetBSD: ext2fs_lookup.c,v 1.16 2000/08/03 20:29:26 thorpej Exp $ */ /* @@ -317,50 +317,8 @@ ext2fs_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; /* capability number of vnode */ - - 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 = VTOI(*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) - 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 = VTOI(pdp); - *vpp = NULL; - } + if ((error = cache_lookup(vdp, vpp, cnp)) >= 0) + return (error); /* * Suppress search for slots unless creating @@ -570,8 +528,10 @@ searchloop: * information cannot be used. */ cnp->cn_flags |= SAVENAME; - if (!lockparent) + if (!lockparent) { VOP_UNLOCK(vdp, 0, p); + cnp->cn_flags |= PDIRUNLOCK; + } return (EJUSTRETURN); } /* @@ -646,8 +606,10 @@ found: return (EPERM); } *vpp = tdp; - if (!lockparent) + if (!lockparent) { VOP_UNLOCK(vdp, 0, p); + cnp->cn_flags |= PDIRUNLOCK; + } return (0); } @@ -671,8 +633,10 @@ found: return (error); *vpp = tdp; cnp->cn_flags |= SAVENAME; - if (!lockparent) + if (!lockparent) { VOP_UNLOCK(vdp, 0, p); + cnp->cn_flags |= PDIRUNLOCK; + } return (0); } @@ -698,14 +662,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 | LK_RETRY, p)) != 0) { - 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) { @@ -714,8 +682,10 @@ found: } else { if ((error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp)) != 0) return (error); - if (!lockparent || !(flags & ISLASTCN)) + if (!lockparent || !(flags & ISLASTCN)) { VOP_UNLOCK(pdp, 0, p); + cnp->cn_flags |= PDIRUNLOCK; + } *vpp = tdp; } |