Date: Sun, 13 Apr 1997 13:58:59 +0900 (JST) From: kato@eclogite.eps.nagoya-u.ac.jp To: FreeBSD-gnats-submit@freebsd.org Subject: kern/3271: deadlock problem in union_fsync Message-ID: <199704130458.NAA00314@marble.eps.nagoya-u.ac.jp> Resent-Message-ID: <199704130500.WAA15842@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 3271 >Category: kern >Synopsis: deadlock problem in union_fsync >Confidential: no >Severity: critical >Priority: high >Responsible: freebsd-bugs >State: open >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sat Apr 12 22:00:00 PDT 1997 >Last-Modified: >Originator: KATO Takenori >Organization: Dept. Earth Planet Sci, Nagoya Univ. >Release: FreeBSD 3.0-CURRENT i386 >Environment: >Description: The function union_fsync tries to lock overlaying vnode object when dolock is not set (that is, targetvp == overlaying vnode object). Current code use FIXUP macro to do this, and never unlocks overlaying vnode object in union_fsync. So, the vnode object will be locked twice and never unlocked. >How-To-Repeat: >Fix: ---------- BEGIN ---------- *** union_vnops.c.ORIG Sun Apr 13 13:43:15 1997 --- union_vnops.c Sun Apr 13 13:43:29 1997 *************** *** 917,933 **** int error = 0; struct proc *p = ap->a_p; struct vnode *targetvp = OTHERVP(ap->a_vp); if (targetvp != NULLVP) { int dolock = (targetvp == LOWERVP(ap->a_vp)); if (dolock) vn_lock(targetvp, LK_EXCLUSIVE | LK_RETRY, p); ! else ! FIXUP(VTOUNION(ap->a_vp), p); error = VOP_FSYNC(targetvp, ap->a_cred, ap->a_waitfor, p); if (dolock) VOP_UNLOCK(targetvp, 0, p); } return (error); --- 917,944 ---- int error = 0; struct proc *p = ap->a_p; struct vnode *targetvp = OTHERVP(ap->a_vp); + struct union_node *un; + int isupperlocked = 0; if (targetvp != NULLVP) { int dolock = (targetvp == LOWERVP(ap->a_vp)); + un = VTOUNION(ap->a_vp); if (dolock) vn_lock(targetvp, LK_EXCLUSIVE | LK_RETRY, p); ! else if ((un->un_flags & UN_ULOCK) == 0 && ! VOP_ISLOCKED(targetvp) == 0) { ! isupperlocked = 1; ! vn_lock(targetvp, LK_EXCLUSIVE | LK_RETRY, p); ! un->un_flags |= UN_ULOCK; ! } error = VOP_FSYNC(targetvp, ap->a_cred, ap->a_waitfor, p); if (dolock) VOP_UNLOCK(targetvp, 0, p); + else if (isupperlocked) { + VOP_UNLOCK(targetvp, 0, p); + un->un_flags &= ~UN_ULOCK; + } } return (error); ---------- END ---------- >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199704130458.NAA00314>