diff options
author | daichi <daichi@FreeBSD.org> | 2012-05-01 07:46:30 +0000 |
---|---|---|
committer | daichi <daichi@FreeBSD.org> | 2012-05-01 07:46:30 +0000 |
commit | 83abcd3986f8b19722ed1891b1aed45f7e85396e (patch) | |
tree | a8b6599b58915fdd3333fa7572c0b2dd8a81f43d /sys/fs/unionfs/union_subr.c | |
parent | 168204e4cfa31cedc08fc18e0a71d7c1183405a4 (diff) | |
download | FreeBSD-src-83abcd3986f8b19722ed1891b1aed45f7e85396e.zip FreeBSD-src-83abcd3986f8b19722ed1891b1aed45f7e85396e.tar.gz |
- fixed a vnode lock hang-up issue.
- fixed an incorrect lock status issue.
- fixed an incorrect lock issue of unionfs root vnode removed.
(pointed out by keith)
- fixed an infinity loop issue.
(pointed out by dumbbell)
- changed to do LK_RELEASE expressly when unlocked.
Submitted by: ozawa@ongs.co.jp
Diffstat (limited to 'sys/fs/unionfs/union_subr.c')
-rw-r--r-- | sys/fs/unionfs/union_subr.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/sys/fs/unionfs/union_subr.c b/sys/fs/unionfs/union_subr.c index 074958c..dbdaa8e 100644 --- a/sys/fs/unionfs/union_subr.c +++ b/sys/fs/unionfs/union_subr.c @@ -2,8 +2,8 @@ * Copyright (c) 1994 Jan-Simon Pendry * Copyright (c) 1994 * The Regents of the University of California. All rights reserved. - * Copyright (c) 2005, 2006 Masanori Ozawa <ozawa@ongs.co.jp>, ONGS Inc. - * Copyright (c) 2006 Daichi Goto <daichi@freebsd.org> + * Copyright (c) 2005, 2006, 2012 Masanori Ozawa <ozawa@ongs.co.jp>, ONGS Inc. + * Copyright (c) 2006, 2012 Daichi Goto <daichi@freebsd.org> * * This code is derived from software contributed to Berkeley by * Jan-Simon Pendry. @@ -350,19 +350,22 @@ unionfs_noderem(struct vnode *vp, struct thread *td) uvp = unp->un_uppervp; dvp = unp->un_dvp; unp->un_lowervp = unp->un_uppervp = NULLVP; - vp->v_vnlock = &(vp->v_lock); vp->v_data = NULL; - lockmgr(vp->v_vnlock, LK_EXCLUSIVE | LK_INTERLOCK, VI_MTX(vp)); + vp->v_object = NULL; + VI_UNLOCK(vp); + if (lvp != NULLVP) - VOP_UNLOCK(lvp, 0); + VOP_UNLOCK(lvp, LK_RELEASE); if (uvp != NULLVP) - VOP_UNLOCK(uvp, 0); - vp->v_object = NULL; + VOP_UNLOCK(uvp, LK_RELEASE); if (dvp != NULLVP && unp->un_hash.le_prev != NULL) unionfs_rem_cached_vnode(unp, dvp); + if (lockmgr(vp->v_vnlock, LK_EXCLUSIVE, VI_MTX(vp)) != 0) + panic("the lock for deletion is unacquirable."); + if (lvp != NULLVP) { vfslocked = VFS_LOCK_GIANT(lvp->v_mount); vrele(lvp); @@ -550,7 +553,7 @@ unionfs_relookup(struct vnode *dvp, struct vnode **vpp, cn->cn_flags |= (cnp->cn_flags & SAVESTART); vref(dvp); - VOP_UNLOCK(dvp, 0); + VOP_UNLOCK(dvp, LK_RELEASE); if ((error = relookup(dvp, vpp, cn))) { uma_zfree(namei_zone, cn->cn_pnbuf); @@ -957,7 +960,7 @@ unionfs_vn_create_on_upper(struct vnode **vpp, struct vnode *udvp, *vpp = vp; unionfs_vn_create_on_upper_free_out1: - VOP_UNLOCK(udvp, 0); + VOP_UNLOCK(udvp, LK_RELEASE); unionfs_vn_create_on_upper_free_out2: if (cn.cn_flags & HASBUF) { |