diff options
author | Alexey Zaytsev <alexey.zaytsev@nexenta.com> | 2012-06-18 21:47:52 -0400 |
---|---|---|
committer | Alexey Zaytsev <alexey.zaytsev@nexenta.com> | 2012-06-18 21:47:52 -0400 |
commit | f097ef9c335ca15d17a8caba066fb2da38a3a1be (patch) | |
tree | eb62f8dc6063f857214875c8af7710e078768764 /usr/src/uts/common/io/blkdev/blkdev.c | |
parent | a3e090fb13431e72eb6751b653b906929410443b (diff) | |
download | illumos-joyent-f097ef9c335ca15d17a8caba066fb2da38a3a1be.tar.gz |
1430 blkdev crashes on synchronous flushes
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Approved by: Dan McDonald <danmcd@nexenta.com>
Diffstat (limited to 'usr/src/uts/common/io/blkdev/blkdev.c')
-rw-r--r-- | usr/src/uts/common/io/blkdev/blkdev.c | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/usr/src/uts/common/io/blkdev/blkdev.c b/usr/src/uts/common/io/blkdev/blkdev.c index b6d59e8834..5b14ea686a 100644 --- a/usr/src/uts/common/io/blkdev/blkdev.c +++ b/usr/src/uts/common/io/blkdev/blkdev.c @@ -1094,9 +1094,11 @@ bd_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *credp, int *rvalp) return (0); } case DKIOCFLUSHWRITECACHE: { - struct dk_callback *dkc; + struct dk_callback *dkc = NULL; + + if (flag & FKIOCTL) + dkc = (void *)arg; - dkc = flag & FKIOCTL ? (void *)arg : NULL; rv = bd_flush_write_cache(bd, dkc); return (rv); } @@ -1437,24 +1439,24 @@ bd_flush_write_cache(bd_t *bd, struct dk_callback *dkc) return (rv); } - if (dkc != NULL) { + /* Make an asynchronous flush, but only if there is a callback */ + if (dkc != NULL && dkc->dkc_callback != NULL) { /* Make a private copy of the callback structure */ dc = kmem_alloc(sizeof (*dc), KM_SLEEP); *dc = *dkc; bp->b_private = dc; bp->b_iodone = bd_flush_write_cache_done; + + bd_submit(bd, xi); + return (0); } + /* In case there is no callback, perform a synchronous flush */ bd_submit(bd, xi); - if (dkc == NULL) { - /* wait synchronously */ - (void) biowait(bp); - rv = geterror(bp); - freerbuf(bp); - } else { - /* deferred via callback */ - rv = 0; - } + (void) biowait(bp); + rv = geterror(bp); + freerbuf(bp); + return (rv); } |