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);
 }