summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_bio.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2000-03-20 10:44:49 +0000
committerphk <phk@FreeBSD.org>2000-03-20 10:44:49 +0000
commita246e10f55686681d4b6bd4dba5ca661b4e34bb0 (patch)
tree13a3ded179bf1de0aff7c33b0eba0534aa2dcf09 /sys/kern/vfs_bio.c
parentf274a82c1448c090620cb35f8516831602a12658 (diff)
downloadFreeBSD-src-a246e10f55686681d4b6bd4dba5ca661b4e34bb0.zip
FreeBSD-src-a246e10f55686681d4b6bd4dba5ca661b4e34bb0.tar.gz
Remove B_READ, B_WRITE and B_FREEBUF and replace them with a new
field in struct buf: b_iocmd. The b_iocmd is enforced to have exactly one bit set. B_WRITE was bogusly defined as zero giving rise to obvious coding mistakes. Also eliminate the redundant struct buf flag B_CALL, it can just as efficiently be done by comparing b_iodone to NULL. Should you get a panic or drop into the debugger, complaining about "b_iocmd", don't continue. It is likely to write on your disk where it should have been reading. This change is a step in the direction towards a stackable BIO capability. A lot of this patch were machine generated (Thanks to style(9) compliance!) Vinum users: Greg has not had time to test this yet, be careful.
Diffstat (limited to 'sys/kern/vfs_bio.c')
-rw-r--r--sys/kern/vfs_bio.c56
1 files changed, 33 insertions, 23 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index a2e8d26..da67cf2 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -501,7 +501,7 @@ bread(struct vnode * vp, daddr_t blkno, int size, struct ucred * cred,
if (curproc != NULL)
curproc->p_stats->p_ru.ru_inblock++;
KASSERT(!(bp->b_flags & B_ASYNC), ("bread: illegal async bp %p", bp));
- bp->b_flags |= B_READ;
+ bp->b_iocmd = BIO_READ;
bp->b_flags &= ~(B_ERROR | B_INVAL);
if (bp->b_rcred == NOCRED) {
if (cred != NOCRED)
@@ -536,7 +536,7 @@ breadn(struct vnode * vp, daddr_t blkno, int size,
if ((bp->b_flags & B_CACHE) == 0) {
if (curproc != NULL)
curproc->p_stats->p_ru.ru_inblock++;
- bp->b_flags |= B_READ;
+ bp->b_iocmd = BIO_READ;
bp->b_flags &= ~(B_ERROR | B_INVAL);
if (bp->b_rcred == NOCRED) {
if (cred != NOCRED)
@@ -556,8 +556,9 @@ breadn(struct vnode * vp, daddr_t blkno, int size,
if ((rabp->b_flags & B_CACHE) == 0) {
if (curproc != NULL)
curproc->p_stats->p_ru.ru_inblock++;
- rabp->b_flags |= B_READ | B_ASYNC;
+ rabp->b_flags |= B_ASYNC;
rabp->b_flags &= ~(B_ERROR | B_INVAL);
+ rabp->b_iocmd = BIO_READ;
if (rabp->b_rcred == NOCRED) {
if (cred != NOCRED)
crhold(cred);
@@ -630,8 +631,10 @@ bwrite(struct buf * bp)
* copy so as to leave this buffer ready for further use.
*/
if ((bp->b_xflags & BX_BKGRDWRITE) && (bp->b_flags & B_ASYNC)) {
- if (bp->b_flags & B_CALL)
+ if (bp->b_iodone != NULL) {
+ printf("bp->b_iodone = %p\n", bp->b_iodone);
panic("bwrite: need chained iodone");
+ }
/* get a new block */
newbp = geteblk(bp->b_bufsize);
@@ -643,7 +646,7 @@ bwrite(struct buf * bp)
newbp->b_blkno = bp->b_blkno;
newbp->b_offset = bp->b_offset;
newbp->b_iodone = vfs_backgroundwritedone;
- newbp->b_flags |= B_ASYNC | B_CALL;
+ newbp->b_flags |= B_ASYNC;
newbp->b_flags &= ~B_INVAL;
/* move over the dependencies */
@@ -664,8 +667,9 @@ bwrite(struct buf * bp)
bp = newbp;
}
- bp->b_flags &= ~(B_READ | B_DONE | B_ERROR);
+ bp->b_flags &= ~(B_DONE | B_ERROR);
bp->b_flags |= B_WRITEINPROG | B_CACHE;
+ bp->b_iocmd = BIO_WRITE;
bp->b_vp->v_numoutput++;
vfs_busy_pages(bp, 1);
@@ -726,11 +730,12 @@ vfs_backgroundwritedone(bp)
}
/*
* This buffer is marked B_NOCACHE, so when it is released
- * by biodone, it will be tossed. We mark it with B_READ
+ * by biodone, it will be tossed. We mark it with BIO_READ
* to avoid biodone doing a second vwakeup.
*/
- bp->b_flags |= B_NOCACHE | B_READ;
- bp->b_flags &= ~(B_CACHE | B_CALL | B_DONE);
+ bp->b_flags |= B_NOCACHE;
+ bp->b_iocmd = BIO_READ;
+ bp->b_flags &= ~(B_CACHE | B_DONE);
bp->b_iodone = 0;
biodone(bp);
}
@@ -806,7 +811,7 @@ bdwrite(struct buf * bp)
/*
* bdirty:
*
- * Turn buffer into delayed write request. We must clear B_READ and
+ * Turn buffer into delayed write request. We must clear BIO_READ and
* B_RELBUF, and we must set B_DELWRI. We reassign the buffer to
* itself to properly update it in the dirty/clean lists. We mark it
* B_DONE to ensure that any asynchronization of the buffer properly
@@ -827,7 +832,8 @@ bdirty(bp)
struct buf *bp;
{
KASSERT(bp->b_qindex == QUEUE_NONE, ("bdirty: buffer %p still on queue %d", bp, bp->b_qindex));
- bp->b_flags &= ~(B_READ|B_RELBUF);
+ bp->b_flags &= ~(B_RELBUF);
+ bp->b_iocmd = BIO_WRITE;
if ((bp->b_flags & B_DELWRI) == 0) {
bp->b_flags |= B_DONE | B_DELWRI;
@@ -946,7 +952,8 @@ brelse(struct buf * bp)
if (bp->b_flags & B_LOCKED)
bp->b_flags &= ~B_ERROR;
- if ((bp->b_flags & (B_READ | B_ERROR | B_INVAL)) == B_ERROR) {
+ if (bp->b_iocmd == BIO_WRITE &&
+ (bp->b_flags & (B_ERROR | B_INVAL)) == B_ERROR) {
/*
* Failed write, redirty. Must clear B_ERROR to prevent
* pages from being scrapped. If B_INVAL is set then
@@ -956,8 +963,8 @@ brelse(struct buf * bp)
*/
bp->b_flags &= ~B_ERROR;
bdirty(bp);
- } else if ((bp->b_flags & (B_NOCACHE | B_INVAL | B_ERROR | B_FREEBUF)) ||
- (bp->b_bufsize <= 0)) {
+ } else if ((bp->b_flags & (B_NOCACHE | B_INVAL | B_ERROR)) ||
+ bp->b_iocmd == BIO_DELETE || (bp->b_bufsize <= 0)) {
/*
* Either a failed I/O or we were asked to free or not
* cache the buffer.
@@ -969,7 +976,7 @@ brelse(struct buf * bp)
--numdirtybuffers;
numdirtywakeup();
}
- bp->b_flags &= ~(B_DELWRI | B_CACHE | B_FREEBUF);
+ bp->b_flags &= ~(B_DELWRI | B_CACHE);
if ((bp->b_flags & B_VMIO) == 0) {
if (bp->b_bufsize)
allocbuf(bp, 0);
@@ -2632,7 +2639,7 @@ biowait(register struct buf * bp)
#if defined(NO_SCHEDULE_MODS)
tsleep(bp, PRIBIO, "biowait", 0);
#else
- if (bp->b_flags & B_READ)
+ if (bp->b_iocmd == BIO_READ)
tsleep(bp, PRIBIO, "biord", 0);
else
tsleep(bp, PRIBIO, "biowr", 0);
@@ -2673,6 +2680,7 @@ void
biodone(register struct buf * bp)
{
int s;
+ void (*b_iodone) __P((struct buf *));
s = splbio();
@@ -2681,20 +2689,21 @@ biodone(register struct buf * bp)
bp->b_flags |= B_DONE;
- if (bp->b_flags & B_FREEBUF) {
+ if (bp->b_iocmd == BIO_DELETE) {
brelse(bp);
splx(s);
return;
}
- if ((bp->b_flags & B_READ) == 0) {
+ if (bp->b_iocmd == BIO_WRITE) {
vwakeup(bp);
}
/* call optional completion function if requested */
- if (bp->b_flags & B_CALL) {
- bp->b_flags &= ~B_CALL;
- (*bp->b_iodone) (bp);
+ if (bp->b_iodone != NULL) {
+ b_iodone = bp->b_iodone;
+ bp->b_iodone = NULL;
+ (*b_iodone) (bp);
splx(s);
return;
}
@@ -2745,7 +2754,8 @@ biodone(register struct buf * bp)
* routines.
*/
iosize = bp->b_bcount - bp->b_resid;
- if ((bp->b_flags & (B_READ|B_FREEBUF|B_INVAL|B_NOCACHE|B_ERROR)) == B_READ) {
+ if (bp->b_iocmd == BIO_READ &&
+ !(bp->b_flags & (B_INVAL|B_NOCACHE|B_ERROR))) {
bp->b_flags |= B_CACHE;
}
@@ -2782,7 +2792,7 @@ biodone(register struct buf * bp)
* already changed correctly ( see bdwrite() ), so we
* only need to do this here in the read case.
*/
- if ((bp->b_flags & B_READ) && !bogusflag && resid > 0) {
+ if ((bp->b_iocmd == BIO_READ) && !bogusflag && resid > 0) {
vfs_page_set_valid(bp, foff, i, m);
}
vm_page_flag_clear(m, PG_ZERO);
OpenPOWER on IntegriCloud