diff --git a/sys/fs/cd9660/cd9660_lookup.c b/sys/fs/cd9660/cd9660_lookup.c index 1b58f44fd67f..b2d5057f631e 100644 --- a/sys/fs/cd9660/cd9660_lookup.c +++ b/sys/fs/cd9660/cd9660_lookup.c @@ -129,6 +129,7 @@ cd9660_lookup(ap) imp = dp->i_mnt; lockparent = flags & LOCKPARENT; wantparent = flags & (LOCKPARENT|WANTPARENT); + cnp->cn_flags &= ~PDIRUNLOCK; /* * We now have a segment name to search for, and a directory to search. @@ -358,11 +359,14 @@ cd9660_lookup(ap) vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, p); 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) { + cnp->cn_flags |= PDIRUNLOCK; + vput(tdp); + return (error); + } + } else + cnp->cn_flags |= PDIRUNLOCK; *vpp = tdp; } else if (dp->i_number == dp->i_ino) { brelse(bp); @@ -374,8 +378,10 @@ cd9660_lookup(ap) brelse(bp); if (error) return (error); - if (!lockparent || !(flags & ISLASTCN)) + if (!lockparent || !(flags & ISLASTCN)) { + cnp->cn_flags |= PDIRUNLOCK; VOP_UNLOCK(pdp, 0, p); + } *vpp = tdp; } diff --git a/sys/fs/cd9660/cd9660_node.c b/sys/fs/cd9660/cd9660_node.c index 4c959779488b..54bace373e46 100644 --- a/sys/fs/cd9660/cd9660_node.c +++ b/sys/fs/cd9660/cd9660_node.c @@ -138,7 +138,7 @@ cd9660_ihashins(ip) *ipp = ip; simple_unlock(&cd9660_ihash_slock); - lockmgr(&ip->i_lock, LK_EXCLUSIVE, (struct simplelock *)0, p); + lockmgr(&ip->i_vnode->v_lock, LK_EXCLUSIVE, (struct simplelock *)0, p); } /* diff --git a/sys/fs/cd9660/cd9660_node.h b/sys/fs/cd9660/cd9660_node.h index 9f56150c183f..100c08e3ff3c 100644 --- a/sys/fs/cd9660/cd9660_node.h +++ b/sys/fs/cd9660/cd9660_node.h @@ -61,7 +61,6 @@ typedef struct { struct iso_node { - struct lock i_lock; /* node lock > Keep this first< */ struct iso_node *i_next, **i_prev; /* hash chain */ struct vnode *i_vnode; /* vnode associated with this inode */ struct vnode *i_devvp; /* vnode for block I/O */ diff --git a/sys/fs/cd9660/cd9660_vfsops.c b/sys/fs/cd9660/cd9660_vfsops.c index 50f3883e108f..09347300e0e5 100644 --- a/sys/fs/cd9660/cd9660_vfsops.c +++ b/sys/fs/cd9660/cd9660_vfsops.c @@ -725,7 +725,11 @@ cd9660_vget_internal(mp, ino, vpp, relocated, isodir) MALLOC(ip, struct iso_node *, sizeof(struct iso_node), M_ISOFSNODE, M_WAITOK); bzero((caddr_t)ip, sizeof(struct iso_node)); - lockinit(&ip->i_lock, PINOD, "isonode", 0, 0); + lockinit(&vp->v_lock, PINOD, "isonode", 0, 0); + /* + * ISOFS uses stdlock and can share lock structure + */ + vp->v_vnlock = &vp->v_lock; vp->v_data = ip; ip->i_vnode = vp; ip->i_dev = dev; diff --git a/sys/isofs/cd9660/cd9660_lookup.c b/sys/isofs/cd9660/cd9660_lookup.c index 1b58f44fd67f..b2d5057f631e 100644 --- a/sys/isofs/cd9660/cd9660_lookup.c +++ b/sys/isofs/cd9660/cd9660_lookup.c @@ -129,6 +129,7 @@ cd9660_lookup(ap) imp = dp->i_mnt; lockparent = flags & LOCKPARENT; wantparent = flags & (LOCKPARENT|WANTPARENT); + cnp->cn_flags &= ~PDIRUNLOCK; /* * We now have a segment name to search for, and a directory to search. @@ -358,11 +359,14 @@ cd9660_lookup(ap) vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, p); 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) { + cnp->cn_flags |= PDIRUNLOCK; + vput(tdp); + return (error); + } + } else + cnp->cn_flags |= PDIRUNLOCK; *vpp = tdp; } else if (dp->i_number == dp->i_ino) { brelse(bp); @@ -374,8 +378,10 @@ cd9660_lookup(ap) brelse(bp); if (error) return (error); - if (!lockparent || !(flags & ISLASTCN)) + if (!lockparent || !(flags & ISLASTCN)) { + cnp->cn_flags |= PDIRUNLOCK; VOP_UNLOCK(pdp, 0, p); + } *vpp = tdp; } diff --git a/sys/isofs/cd9660/cd9660_node.c b/sys/isofs/cd9660/cd9660_node.c index 4c959779488b..54bace373e46 100644 --- a/sys/isofs/cd9660/cd9660_node.c +++ b/sys/isofs/cd9660/cd9660_node.c @@ -138,7 +138,7 @@ cd9660_ihashins(ip) *ipp = ip; simple_unlock(&cd9660_ihash_slock); - lockmgr(&ip->i_lock, LK_EXCLUSIVE, (struct simplelock *)0, p); + lockmgr(&ip->i_vnode->v_lock, LK_EXCLUSIVE, (struct simplelock *)0, p); } /* diff --git a/sys/isofs/cd9660/cd9660_node.h b/sys/isofs/cd9660/cd9660_node.h index 9f56150c183f..100c08e3ff3c 100644 --- a/sys/isofs/cd9660/cd9660_node.h +++ b/sys/isofs/cd9660/cd9660_node.h @@ -61,7 +61,6 @@ typedef struct { struct iso_node { - struct lock i_lock; /* node lock > Keep this first< */ struct iso_node *i_next, **i_prev; /* hash chain */ struct vnode *i_vnode; /* vnode associated with this inode */ struct vnode *i_devvp; /* vnode for block I/O */ diff --git a/sys/isofs/cd9660/cd9660_vfsops.c b/sys/isofs/cd9660/cd9660_vfsops.c index 50f3883e108f..09347300e0e5 100644 --- a/sys/isofs/cd9660/cd9660_vfsops.c +++ b/sys/isofs/cd9660/cd9660_vfsops.c @@ -725,7 +725,11 @@ cd9660_vget_internal(mp, ino, vpp, relocated, isodir) MALLOC(ip, struct iso_node *, sizeof(struct iso_node), M_ISOFSNODE, M_WAITOK); bzero((caddr_t)ip, sizeof(struct iso_node)); - lockinit(&ip->i_lock, PINOD, "isonode", 0, 0); + lockinit(&vp->v_lock, PINOD, "isonode", 0, 0); + /* + * ISOFS uses stdlock and can share lock structure + */ + vp->v_vnlock = &vp->v_lock; vp->v_data = ip; ip->i_vnode = vp; ip->i_dev = dev;