summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_bio.c
diff options
context:
space:
mode:
authordillon <dillon@FreeBSD.org>2001-11-05 18:48:54 +0000
committerdillon <dillon@FreeBSD.org>2001-11-05 18:48:54 +0000
commit1147eaf58a59e2d2aa15fb9395dc939c237e6269 (patch)
treede03e156782fad9ffef4684a7cf3f1908967e835 /sys/kern/vfs_bio.c
parent815c903d62ca6edef2915e089d29443365138986 (diff)
downloadFreeBSD-src-1147eaf58a59e2d2aa15fb9395dc939c237e6269.zip
FreeBSD-src-1147eaf58a59e2d2aa15fb9395dc939c237e6269.tar.gz
Implement IO_NOWDRAIN and B_NOWDRAIN - prevents the buffer cache from blocking
in wdrain during a write. This flag needs to be used in devices whos strategy routines turn-around and issue another high level I/O, such as when MD turns around and issues a VOP_WRITE to vnode backing store, in order to avoid deadlocking the dirty buffer draining code. Remove a vprintf() warning from MD when the backing vnode is found to be in-use. The syncer of buf_daemon could be flushing the backing vnode at the time of an MD operation so the warning is not correct. MFC after: 1 week
Diffstat (limited to 'sys/kern/vfs_bio.c')
-rw-r--r--sys/kern/vfs_bio.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index 635e394..ba55013 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -758,11 +758,15 @@ bwrite(struct buf * bp)
int rtval = bufwait(bp);
brelse(bp);
return (rtval);
- } else {
+ } else if ((oldflags & B_NOWDRAIN) == 0) {
/*
* don't allow the async write to saturate the I/O
- * system. There is no chance of deadlock here because
- * we are blocking on I/O that is already in-progress.
+ * system. Deadlocks can occur only if a device strategy
+ * routine (like in MD) turns around and issues another
+ * high-level write, in which case B_NOWDRAIN is expected
+ * to be set. Otherwise we will not deadlock here because
+ * we are blocking waiting for I/O that is already in-progress
+ * to complete.
*/
waitrunningbufspace();
}
@@ -1286,7 +1290,8 @@ brelse(struct buf * bp)
/* unlock */
BUF_UNLOCK(bp);
- bp->b_flags &= ~(B_ASYNC | B_NOCACHE | B_AGE | B_RELBUF | B_DIRECT);
+ bp->b_flags &= ~(B_ASYNC | B_NOCACHE | B_AGE | B_RELBUF |
+ B_DIRECT | B_NOWDRAIN);
bp->b_ioflags &= ~BIO_ORDERED;
if ((bp->b_flags & B_DELWRI) == 0 && (bp->b_xflags & BX_VNDIRTY))
panic("brelse: not dirty");
OpenPOWER on IntegriCloud