- Introduce a new function bremfreel() that does a bremfree with the buf

queue lock already held.
 - In getblk() and flushbufqueues() use bremfreel() while we still have the
   buf queue lock held to keep the lists consistent.
 - Add LK_NOWAIT to two cases where we're essentially asserting that the bufs
   are not locked while acquiring the locks.  This will make sure that we get
   the appropriate panic() and not another one for sleeping with a lock held.
This commit is contained in:
Jeff Roberson 2003-02-16 10:43:06 +00:00
parent 5e8feb5bed
commit 71146186a1

View File

@ -84,6 +84,7 @@ static int vfs_bio_clcheck(struct vnode *vp, int size,
daddr_t lblkno, daddr_t blkno);
static int flushbufqueues(void);
static void buf_daemon(void);
void bremfreel(struct buf * bp);
int vmiodirenable = TRUE;
SYSCTL_INT(_vfs, OID_AUTO, vmiodirenable, CTLFLAG_RW, &vmiodirenable, 0,
@ -653,13 +654,20 @@ bfreekva(struct buf * bp)
*/
void
bremfree(struct buf * bp)
{
mtx_lock(&bqlock);
bremfreel(bp);
mtx_unlock(&bqlock);
}
void
bremfreel(struct buf * bp)
{
int s = splbio();
int old_qindex = bp->b_qindex;
GIANT_REQUIRED;
mtx_lock(&bqlock);
if (bp->b_qindex != QUEUE_NONE) {
KASSERT(BUF_REFCNT(bp) == 1, ("bremfree: bp %p not locked",bp));
TAILQ_REMOVE(&bufqueues[bp->b_qindex], bp, b_freelist);
@ -686,7 +694,6 @@ bremfree(struct buf * bp)
break;
}
}
mtx_unlock(&bqlock);
splx(s);
}
@ -1865,9 +1872,8 @@ restart:
if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT) != 0)
panic("getnewbuf: locked buf");
/* XXX bqlock needs to be held across bremfree() */
bremfreel(bp);
mtx_unlock(&bqlock);
bremfree(bp);
if (qindex == QUEUE_CLEAN) {
if (bp->b_flags & B_VMIO) {
@ -2141,10 +2147,10 @@ flushbufqueues(void)
if ((bp->b_xflags & BX_BKGRDINPROG) != 0)
continue;
if (bp->b_flags & B_INVAL) {
if (BUF_LOCK(bp, LK_EXCLUSIVE) != 0)
if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT) != 0)
panic("flushbufqueues: locked buf");
bremfreel(bp);
mtx_unlock(&bqlock);
bremfree(bp);
brelse(bp);
return (1);
}
@ -2176,10 +2182,10 @@ flushbufqueues(void)
if ((bp->b_xflags & BX_BKGRDINPROG) != 0)
continue;
if (bp->b_flags & B_INVAL) {
if (BUF_LOCK(bp, LK_EXCLUSIVE) != 0)
if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT) != 0)
panic("flushbufqueues: locked buf");
bremfreel(bp);
mtx_unlock(&bqlock);
bremfree(bp);
brelse(bp);
return (1);
}