Introducing B_LOCKED buffer flag
With this flag we can protect buffers that will be used by WAPBL while
doing the log of transactions.
--
Walter Neto
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index 63bd7ca..aa0575f 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -743,6 +743,10 @@ brelse(struct buf *bp)
* Determine which queue the buffer should be on, then put it there.
*/
+ /* If it's locked, don't report an error; try again later */
+ if (ISSET(bp->b_flags, (B_LOCKED|B_ERROR)) == (B_LOCKED|B_ERROR))
+ CLR(bp->b_flags, B_ERROR);
+
/* If it's not cacheable, or an error, mark it invalid. */
if (ISSET(bp->b_flags, (B_NOCACHE|B_ERROR)))
SET(bp->b_flags, B_INVAL);
diff --git a/sys/kern/vfs_biomem.c b/sys/kern/vfs_biomem.c
index da0a355..9f98c70 100644
--- a/sys/kern/vfs_biomem.c
+++ b/sys/kern/vfs_biomem.c
@@ -89,7 +89,7 @@ buf_acquire_nomap(struct buf *bp)
{
splassert(IPL_BIO);
SET(bp->b_flags, B_BUSY);
- if (bp->b_data != NULL) {
+ if (bp->b_data != NULL && !(bp->b_flags & B_LOCKED)) {
TAILQ_REMOVE(&buf_valist, bp, b_valist);
bcstats.kvaslots_avail--;
bcstats.busymapped++;
@@ -143,8 +143,11 @@ buf_map(struct buf *bp)
pmap_update(pmap_kernel());
bp->b_data = (caddr_t)va;
} else {
- TAILQ_REMOVE(&buf_valist, bp, b_valist);
- bcstats.kvaslots_avail--;
+ if (!(bp->b_flags & B_LOCKED)) {
+ TAILQ_REMOVE(&buf_valist, bp, b_valist);
+ bcstats.kvaslots_avail--;
+ } else
+ return;
}
bcstats.busymapped++;
@@ -157,7 +160,7 @@ buf_release(struct buf *bp)
KASSERT(bp->b_flags & B_BUSY);
splassert(IPL_BIO);
- if (bp->b_data) {
+ if (bp->b_data && !(bp->b_flags & B_LOCKED)) {
bcstats.busymapped--;
TAILQ_INSERT_TAIL(&buf_valist, bp, b_valist);
bcstats.kvaslots_avail++;
@@ -191,6 +194,7 @@ buf_dealloc_mem(struct buf *bp)
bp->b_data = NULL;
if (data) {
+ KASSERT(!(bp->b_flags & B_LOCKED));
if (bp->b_flags & B_BUSY)
bcstats.busymapped--;
pmap_kremove((vaddr_t)data, bp->b_bufsize);
@@ -237,6 +241,7 @@ buf_fix_mapping(struct buf *bp, vsize_t newsize)
* buffers read in by bread_cluster
*/
bp->b_bufsize = newsize;
+ KASSERT(!(bp->b_flags & B_LOCKED));
}
}
diff --git a/sys/sys/buf.h b/sys/sys/buf.h
index fd38c28..28b1a32 100644
--- a/sys/sys/buf.h
+++ b/sys/sys/buf.h
@@ -221,12 +221,14 @@ struct bufcache {
#define B_COLD 0x01000000 /* buffer is on the cold queue
*/
#define B_BC 0x02000000 /* buffer is managed by the
cache */
#define B_DMA 0x04000000 /* buffer is DMA reachable */
+#define B_LOCKED 0x08000000 /* Locked in core (not
reusable). */
#define B_BITS "\20\001AGE\002NEEDCOMMIT\003ASYNC\004BAD\005BUSY" \
"\006CACHE\007CALL\010DELWRI\011DONE\012EINTR\013ERROR" \
"\014INVAL\015NOCACHE\016PHYS\017RAW\020READ" \
"\021WANTED\022WRITEINPROG\023XXX(FORMAT)\024DEFERRED" \
- "\025SCANNED\026DAEMON\027RELEASED\030WARM\031COLD\032BC\033DMA"
+ "\025SCANNED\026DAEMON\027RELEASED\030WARM\031COLD\032BC\033DMA" \
+ "\034LOCKED"
/*
* This structure describes a clustered I/O. It is stored in the b_saveaddr