svn commit: r348535 - vendor-sys/illumos/dist/uts/common/fs/zfs

Alexander Motin mav at FreeBSD.org
Mon Jun 3 15:23:23 UTC 2019


Author: mav
Date: Mon Jun  3 15:23:21 2019
New Revision: 348535
URL: https://svnweb.freebsd.org/changeset/base/348535

Log:
  9677 panic from zio_write_gang_block() when creating dump device on fragmented rpool
  
  illumos/illumos-gate at 7341a7de4f0489193e0cfe11049a7bcf1596a4db
  
  Reviewed by: Matt Ahrens <matt at delphix.com>
  Reviewed by: George Wilson <george.wilson at delphix.com>
  Reviewed by: Prashanth Sreenivasa <pks at delphix.com>
  Approved by: Robert Mustacchi <rm at joyent.com>
  Author:     Brad Lewis <brad.lewis at delphix.com>

Modified:
  vendor-sys/illumos/dist/uts/common/fs/zfs/zio.c

Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/zio.c
==============================================================================
--- vendor-sys/illumos/dist/uts/common/fs/zfs/zio.c	Mon Jun  3 15:19:23 2019	(r348534)
+++ vendor-sys/illumos/dist/uts/common/fs/zfs/zio.c	Mon Jun  3 15:23:21 2019	(r348535)
@@ -2192,7 +2192,13 @@ zio_write_gang_member_ready(zio_t *zio)
 static void
 zio_write_gang_done(zio_t *zio)
 {
-	abd_put(zio->io_abd);
+	/*
+	 * The io_abd field will be NULL for a zio with no data.  The io_flags
+	 * will initially have the ZIO_FLAG_NODATA bit flag set, but we can't
+	 * check for it here as it is cleared in zio_ready.
+	 */
+	if (zio->io_abd != NULL)
+		abd_put(zio->io_abd);
 }
 
 static int
@@ -2213,11 +2219,12 @@ zio_write_gang_block(zio_t *pio)
 	int gbh_copies = MIN(copies + 1, spa_max_replication(spa));
 	zio_prop_t zp;
 	int error;
+	boolean_t has_data = !(pio->io_flags & ZIO_FLAG_NODATA);
 
 	int flags = METASLAB_HINTBP_FAVOR | METASLAB_GANG_HEADER;
 	if (pio->io_flags & ZIO_FLAG_IO_ALLOCATING) {
 		ASSERT(pio->io_priority == ZIO_PRIORITY_ASYNC_WRITE);
-		ASSERT(!(pio->io_flags & ZIO_FLAG_NODATA));
+		ASSERT(has_data);
 
 		flags |= METASLAB_ASYNC_ALLOC;
 		VERIFY(refcount_held(&mc->mc_alloc_slots[pio->io_allocator],
@@ -2241,7 +2248,7 @@ zio_write_gang_block(zio_t *pio)
 	if (error) {
 		if (pio->io_flags & ZIO_FLAG_IO_ALLOCATING) {
 			ASSERT(pio->io_priority == ZIO_PRIORITY_ASYNC_WRITE);
-			ASSERT(!(pio->io_flags & ZIO_FLAG_NODATA));
+			ASSERT(has_data);
 
 			/*
 			 * If we failed to allocate the gang block header then
@@ -2294,14 +2301,15 @@ zio_write_gang_block(zio_t *pio)
 		zp.zp_nopwrite = B_FALSE;
 
 		zio_t *cio = zio_write(zio, spa, txg, &gbh->zg_blkptr[g],
-		    abd_get_offset(pio->io_abd, pio->io_size - resid), lsize,
-		    lsize, &zp, zio_write_gang_member_ready, NULL, NULL,
+		    has_data ? abd_get_offset(pio->io_abd, pio->io_size -
+		    resid) : NULL, lsize, lsize, &zp,
+		    zio_write_gang_member_ready, NULL, NULL,
 		    zio_write_gang_done, &gn->gn_child[g], pio->io_priority,
 		    ZIO_GANG_CHILD_FLAGS(pio), &pio->io_bookmark);
 
 		if (pio->io_flags & ZIO_FLAG_IO_ALLOCATING) {
 			ASSERT(pio->io_priority == ZIO_PRIORITY_ASYNC_WRITE);
-			ASSERT(!(pio->io_flags & ZIO_FLAG_NODATA));
+			ASSERT(has_data);
 
 			/*
 			 * Gang children won't throttle but we should


More information about the svn-src-all mailing list