- 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:
parent
5e8feb5bed
commit
71146186a1
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user