diff options
author | kato <kato@FreeBSD.org> | 1998-01-18 07:56:41 +0000 |
---|---|---|
committer | kato <kato@FreeBSD.org> | 1998-01-18 07:56:41 +0000 |
commit | 5ff1564039736f2a608d963c03de2883d9430745 (patch) | |
tree | ce7597cb27c576d77d7ffb0fb869dae2916f8fe4 /sys/fs/unionfs/union_vfsops.c | |
parent | a909b80bf1b408bad3f554b9072f26ff3a3b94fb (diff) | |
download | FreeBSD-src-5ff1564039736f2a608d963c03de2883d9430745.zip FreeBSD-src-5ff1564039736f2a608d963c03de2883d9430745.tar.gz |
Improve and revise fixes for locking violation.
Obtained from: NetBSD/pc98
Diffstat (limited to 'sys/fs/unionfs/union_vfsops.c')
-rw-r--r-- | sys/fs/unionfs/union_vfsops.c | 40 |
1 files changed, 17 insertions, 23 deletions
diff --git a/sys/fs/unionfs/union_vfsops.c b/sys/fs/unionfs/union_vfsops.c index 753afd6..90da301 100644 --- a/sys/fs/unionfs/union_vfsops.c +++ b/sys/fs/unionfs/union_vfsops.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * @(#)union_vfsops.c 8.20 (Berkeley) 5/20/95 - * $Id: union_vfsops.c,v 1.21 1997/10/12 20:24:57 phk Exp $ + * $Id: union_vfsops.c,v 1.22 1997/11/18 15:07:35 phk Exp $ */ /* @@ -132,12 +132,9 @@ union_mount(mp, path, data, ndp, p) /* * Unlock lower node to avoid deadlock. - * (XXX) VOP_ISLOCKED is needed? */ - if ((lowerrootvp->v_op == union_vnodeop_p) && VOP_ISLOCKED(lowerrootvp)) { + if (lowerrootvp->v_op == union_vnodeop_p) VOP_UNLOCK(lowerrootvp, 0, p); - islowerunlocked = 1; - } /* * Find upper node. @@ -146,11 +143,7 @@ union_mount(mp, path, data, ndp, p) UIO_USERSPACE, args.target, p); error = namei(ndp); - /* - * Re-lock vnode. - * (XXX) VOP_ISLOCKED is needed? - */ - if (islowerunlocked && !VOP_ISLOCKED(lowerrootvp)) + if (lowerrootvp->v_op == union_vnodeop_p) vn_lock(lowerrootvp, LK_EXCLUSIVE | LK_RETRY, p); if (error) goto bad; @@ -404,27 +397,24 @@ union_root(mp, vpp) struct union_mount *um = MOUNTTOUNIONMOUNT(mp); int error; int loselock; + int lockadj = 0; + + if (um->um_lowervp && um->um_op != UNMNT_BELOW && + VOP_ISLOCKED(um->um_lowervp)) { + VREF(um->um_lowervp); + VOP_UNLOCK(um->um_lowervp, 0, p); + lockadj = 1; + } /* * Return locked reference to root. */ VREF(um->um_uppervp); if ((um->um_op == UNMNT_BELOW) && - VOP_ISLOCKED(um->um_uppervp)) { + VOP_ISLOCKED(um->um_uppervp)) { loselock = 1; } else { - if (VOP_ISLOCKED(um->um_uppervp)) { - /* - * XXX - * Should we check type of node? - */ -#ifdef DIAGNOSTIC - printf("union_root: multi union mount?"); -#endif - vrele(um->um_uppervp); - return EDEADLK; - } else - vn_lock(um->um_uppervp, LK_EXCLUSIVE | LK_RETRY, p); + vn_lock(um->um_uppervp, LK_EXCLUSIVE | LK_RETRY, p); loselock = 0; } if (um->um_lowervp) @@ -448,6 +438,10 @@ union_root(mp, vpp) if (loselock) VTOUNION(*vpp)->un_flags &= ~UN_ULOCK; } + if (lockadj) { + vn_lock(um->um_lowervp, LK_EXCLUSIVE | LK_RETRY, p); + vrele(um->um_lowervp); + } return (error); } |