Mercurial > illumos > illumos-gate
changeset 13728:142190a1b491
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>
author | Alexey Zaytsev <alexey.zaytsev@nexenta.com> |
---|---|
date | Mon, 18 Jun 2012 21:47:52 -0400 |
parents | 826d789b2aae |
children | 9823b670b193 |
files | usr/src/uts/common/io/blkdev/blkdev.c |
diffstat | 1 files changed, 14 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/io/blkdev/blkdev.c Mon Jun 18 21:47:51 2012 -0400 +++ b/usr/src/uts/common/io/blkdev/blkdev.c Mon Jun 18 21:47:52 2012 -0400 @@ -1094,9 +1094,11 @@ return (0); } case DKIOCFLUSHWRITECACHE: { - struct dk_callback *dkc; + struct dk_callback *dkc = NULL; - dkc = flag & FKIOCTL ? (void *)arg : NULL; + if (flag & FKIOCTL) + dkc = (void *)arg; + rv = bd_flush_write_cache(bd, dkc); return (rv); } @@ -1437,24 +1439,24 @@ 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); }