Author: mav
Date: Mon Jun  3 17:27:25 2019
New Revision: 348558
URL: https://svnweb.freebsd.org/changeset/base/348558

Log:
  MFV r348535: 9677 panic from zio_write_gang_block() when creating dump device 
on fragmented rpool
  
  illumos/illumos-gate@7341a7de4f0489193e0cfe11049a7bcf1596a4db
  
  Reviewed by: Matt Ahrens <m...@delphix.com>
  Reviewed by: George Wilson <george.wil...@delphix.com>
  Reviewed by: Prashanth Sreenivasa <p...@delphix.com>
  Approved by: Robert Mustacchi <r...@joyent.com>
  Author:     Brad Lewis <brad.le...@delphix.com>

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
Directory Properties:
  head/sys/cddl/contrib/opensolaris/   (props changed)

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c   Mon Jun  3 
17:19:05 2019        (r348557)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c   Mon Jun  3 
17:27:25 2019        (r348558)
@@ -2319,7 +2319,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 zio_t *
@@ -2340,11 +2346,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],
@@ -2368,7 +2375,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
@@ -2421,14 +2428,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
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to