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>
index | next in thread | raw e-mail
>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:
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199704130458.NAA00314>
