Date: Wed, 5 Mar 1997 04:01:49 +0900 (JST) From: kato@eclogite.eps.nagoya-u.ac.jp To: FreeBSD-gnats-submit@freebsd.org Subject: kern/2875: vinvalbuf() clobbers b_vnbufs chain Message-ID: <199703041901.EAA01847@gneiss.eps.nagoya-u.ac.jp> Resent-Message-ID: <199703041910.LAA08444@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 2875 >Category: kern >Synopsis: vinvalbuf() may clobber b_vnbufs chain. >Confidential: no >Severity: critical >Priority: high >Responsible: freebsd-bugs >State: open >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Mar 4 11:10:01 PST 1997 >Last-Modified: >Originator: KATO Takenori >Organization: Dept. Earth Planet. Sci, Nagoya Univ, Japan >Release: FreeBSD 2.2-GAMMA i386 >Environment: >Description: The function vinvalbuf() in vfs_subr.c may clober b_vnbufs chain. in vinvalbuf(): s = splbio(); for (;;) { ... for (bp = blist; bp; bp = nbp) { ... if (bp->b_flags & B_BUSY) { ... splx(s); <--- (1) ... break; <--- (2) } } } Because disk I/O interruption is unmasked at (1), b_vnbufs is operated without splbio() after `break' at (2). >How-To-Repeat: >Fix: *** vfs_subr.c.orig Wed Mar 5 03:03:56 1997 --- vfs_subr.c Wed Mar 5 03:44:00 1997 *************** *** 481,488 **** panic("vinvalbuf: dirty bufs"); } - s = splbio(); for (;;) { if ((blist = vp->v_cleanblkhd.lh_first) && (flags & V_SAVEMETA)) while (blist && blist->b_lblkno < 0) blist = blist->b_vnbufs.le_next; --- 481,488 ---- panic("vinvalbuf: dirty bufs"); } for (;;) { + s = splbio(); if ((blist = vp->v_cleanblkhd.lh_first) && (flags & V_SAVEMETA)) while (blist && blist->b_lblkno < 0) blist = blist->b_vnbufs.le_next; *************** *** 502,510 **** error = tsleep((caddr_t) bp, slpflag | (PRIBIO + 1), "vinvalbuf", slptimeo); ! splx(s); ! if (error) return (error); break; } bremfree(bp); --- 502,511 ---- error = tsleep((caddr_t) bp, slpflag | (PRIBIO + 1), "vinvalbuf", slptimeo); ! if (error) { ! splx(s); return (error); + } break; } bremfree(bp); *************** *** 522,527 **** --- 523,529 ---- bp->b_flags |= (B_INVAL|B_NOCACHE|B_RELBUF); brelse(bp); } + splx(s); } splx(s); >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199703041901.EAA01847>