diff options
author | jeff <jeff@FreeBSD.org> | 2003-02-16 10:43:06 +0000 |
---|---|---|
committer | jeff <jeff@FreeBSD.org> | 2003-02-16 10:43:06 +0000 |
commit | de87d496d3c8f9ff6c6669d4289e62426e3e6664 (patch) | |
tree | 11416308ca8fefa1d2cefc96a4d688ee570c5b90 | |
parent | bdd105307471f46e2cca3dd3a5c2ee859c6863ac (diff) | |
download | FreeBSD-src-de87d496d3c8f9ff6c6669d4289e62426e3e6664.zip FreeBSD-src-de87d496d3c8f9ff6c6669d4289e62426e3e6664.tar.gz |
- 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.
-rw-r--r-- | sys/kern/vfs_bio.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 3dbbed6..104043c 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -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, @@ -654,12 +655,19 @@ 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); } |