kern/39052: fix broken assertion. We can have a BC_BUSY buffer in the LRU
queue, if it's being flushed. But in this case, we'll also have B_VFLUSH. While there fix checkfreelist() so that it can be used to check that a buffer is not in the free lists.
This commit is contained in:
parent
163f9db0b9
commit
52346627a5
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: vfs_bio.c,v 1.205 2008/06/17 19:14:14 mlelstv Exp $ */
|
/* $NetBSD: vfs_bio.c,v 1.206 2008/07/06 15:00:45 bouyer Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
|
* Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
|
||||||
|
@ -107,7 +107,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: vfs_bio.c,v 1.205 2008/06/17 19:14:14 mlelstv Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: vfs_bio.c,v 1.206 2008/07/06 15:00:45 bouyer Exp $");
|
||||||
|
|
||||||
#include "fs_ffs.h"
|
#include "fs_ffs.h"
|
||||||
#include "opt_bufcache.h"
|
#include "opt_bufcache.h"
|
||||||
|
@ -167,7 +167,7 @@ static void binsheadfree(buf_t *, struct bqueue *);
|
||||||
static void binstailfree(buf_t *, struct bqueue *);
|
static void binstailfree(buf_t *, struct bqueue *);
|
||||||
int count_lock_queue(void); /* XXX */
|
int count_lock_queue(void); /* XXX */
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static int checkfreelist(buf_t *, struct bqueue *);
|
static int checkfreelist(buf_t *, struct bqueue *, int);
|
||||||
#endif
|
#endif
|
||||||
static void biointr(void *);
|
static void biointr(void *);
|
||||||
static void biodone2(buf_t *);
|
static void biodone2(buf_t *);
|
||||||
|
@ -285,7 +285,7 @@ buf_setwm(void)
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
int debug_verify_freelist = 0;
|
int debug_verify_freelist = 0;
|
||||||
static int
|
static int
|
||||||
checkfreelist(buf_t *bp, struct bqueue *dp)
|
checkfreelist(buf_t *bp, struct bqueue *dp, int ison)
|
||||||
{
|
{
|
||||||
buf_t *b;
|
buf_t *b;
|
||||||
|
|
||||||
|
@ -294,10 +294,10 @@ checkfreelist(buf_t *bp, struct bqueue *dp)
|
||||||
|
|
||||||
TAILQ_FOREACH(b, &dp->bq_queue, b_freelist) {
|
TAILQ_FOREACH(b, &dp->bq_queue, b_freelist) {
|
||||||
if (b == bp)
|
if (b == bp)
|
||||||
return 1;
|
return ison ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return ison ? 0 : 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -309,6 +309,7 @@ static void
|
||||||
binsheadfree(buf_t *bp, struct bqueue *dp)
|
binsheadfree(buf_t *bp, struct bqueue *dp)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
KASSERT(mutex_owned(&bufcache_lock));
|
||||||
KASSERT(bp->b_freelistindex == -1);
|
KASSERT(bp->b_freelistindex == -1);
|
||||||
TAILQ_INSERT_HEAD(&dp->bq_queue, bp, b_freelist);
|
TAILQ_INSERT_HEAD(&dp->bq_queue, bp, b_freelist);
|
||||||
dp->bq_bytes += bp->b_bufsize;
|
dp->bq_bytes += bp->b_bufsize;
|
||||||
|
@ -319,6 +320,7 @@ static void
|
||||||
binstailfree(buf_t *bp, struct bqueue *dp)
|
binstailfree(buf_t *bp, struct bqueue *dp)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
KASSERT(mutex_owned(&bufcache_lock));
|
||||||
KASSERT(bp->b_freelistindex == -1);
|
KASSERT(bp->b_freelistindex == -1);
|
||||||
TAILQ_INSERT_TAIL(&dp->bq_queue, bp, b_freelist);
|
TAILQ_INSERT_TAIL(&dp->bq_queue, bp, b_freelist);
|
||||||
dp->bq_bytes += bp->b_bufsize;
|
dp->bq_bytes += bp->b_bufsize;
|
||||||
|
@ -335,7 +337,7 @@ bremfree(buf_t *bp)
|
||||||
|
|
||||||
KASSERT(bqidx != -1);
|
KASSERT(bqidx != -1);
|
||||||
dp = &bufqueues[bqidx];
|
dp = &bufqueues[bqidx];
|
||||||
KDASSERT(checkfreelist(bp, dp));
|
KDASSERT(checkfreelist(bp, dp, 1));
|
||||||
KASSERT(dp->bq_bytes >= bp->b_bufsize);
|
KASSERT(dp->bq_bytes >= bp->b_bufsize);
|
||||||
TAILQ_REMOVE(&dp->bq_queue, bp, b_freelist);
|
TAILQ_REMOVE(&dp->bq_queue, bp, b_freelist);
|
||||||
dp->bq_bytes -= bp->b_bufsize;
|
dp->bq_bytes -= bp->b_bufsize;
|
||||||
|
@ -1007,16 +1009,16 @@ brelsel(buf_t *bp, int set)
|
||||||
CLR(bp->b_cflags, BC_VFLUSH);
|
CLR(bp->b_cflags, BC_VFLUSH);
|
||||||
if (!ISSET(bp->b_cflags, BC_INVAL|BC_AGE) &&
|
if (!ISSET(bp->b_cflags, BC_INVAL|BC_AGE) &&
|
||||||
!ISSET(bp->b_flags, B_LOCKED) && bp->b_error == 0) {
|
!ISSET(bp->b_flags, B_LOCKED) && bp->b_error == 0) {
|
||||||
KDASSERT(checkfreelist(bp, &bufqueues[BQ_LRU]));
|
KDASSERT(checkfreelist(bp, &bufqueues[BQ_LRU], 1));
|
||||||
goto already_queued;
|
goto already_queued;
|
||||||
} else {
|
} else {
|
||||||
bremfree(bp);
|
bremfree(bp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KDASSERT(checkfreelist(bp, &bufqueues[BQ_AGE]));
|
KDASSERT(checkfreelist(bp, &bufqueues[BQ_AGE], 0));
|
||||||
KDASSERT(checkfreelist(bp, &bufqueues[BQ_LRU]));
|
KDASSERT(checkfreelist(bp, &bufqueues[BQ_LRU], 0));
|
||||||
KDASSERT(checkfreelist(bp, &bufqueues[BQ_LOCKED]));
|
KDASSERT(checkfreelist(bp, &bufqueues[BQ_LOCKED], 0));
|
||||||
|
|
||||||
if ((bp->b_bufsize <= 0) || ISSET(bp->b_cflags, BC_INVAL)) {
|
if ((bp->b_bufsize <= 0) || ISSET(bp->b_cflags, BC_INVAL)) {
|
||||||
/*
|
/*
|
||||||
|
@ -1313,7 +1315,7 @@ getnewbuf(int slpflag, int slptimeo, int from_bufq)
|
||||||
|
|
||||||
if ((bp = TAILQ_FIRST(&bufqueues[BQ_AGE].bq_queue)) != NULL ||
|
if ((bp = TAILQ_FIRST(&bufqueues[BQ_AGE].bq_queue)) != NULL ||
|
||||||
(bp = TAILQ_FIRST(&bufqueues[BQ_LRU].bq_queue)) != NULL) {
|
(bp = TAILQ_FIRST(&bufqueues[BQ_LRU].bq_queue)) != NULL) {
|
||||||
KASSERT(!ISSET(bp->b_cflags, BC_BUSY));
|
KASSERT(!ISSET(bp->b_cflags, BC_BUSY) || ISSET(bp->b_cflags, BC_VFLUSH));
|
||||||
bremfree(bp);
|
bremfree(bp);
|
||||||
|
|
||||||
/* Buffer is no longer on free lists. */
|
/* Buffer is no longer on free lists. */
|
||||||
|
|
Loading…
Reference in New Issue