summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/io/blkdev/blkdev.c
diff options
context:
space:
mode:
authorAlexey Zaytsev <alexey.zaytsev@nexenta.com>2012-06-18 21:47:52 -0400
committerAlexey Zaytsev <alexey.zaytsev@nexenta.com>2012-06-18 21:47:52 -0400
commitf097ef9c335ca15d17a8caba066fb2da38a3a1be (patch)
treeeb62f8dc6063f857214875c8af7710e078768764 /usr/src/uts/common/io/blkdev/blkdev.c
parenta3e090fb13431e72eb6751b653b906929410443b (diff)
downloadillumos-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.c26
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);
}