summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2003-02-16 10:43:06 +0000
committerjeff <jeff@FreeBSD.org>2003-02-16 10:43:06 +0000
commitde87d496d3c8f9ff6c6669d4289e62426e3e6664 (patch)
tree11416308ca8fefa1d2cefc96a4d688ee570c5b90
parentbdd105307471f46e2cca3dd3a5c2ee859c6863ac (diff)
downloadFreeBSD-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.c22
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);
}
OpenPOWER on IntegriCloud