Author: mav Date: Tue Jun 11 14:18:04 2019 New Revision: 348908 URL: https://svnweb.freebsd.org/changeset/base/348908
Log: MFC r348558: MFV r348535: 9677 panic from zio_write_gang_block() when creating dump device on fragmented rpool illumos/illumos-gate@7341a7de4f0489193e0cfe11049a7bcf1596a4db Reviewed by: Matt Ahrens <[email protected]> Reviewed by: George Wilson <[email protected]> Reviewed by: Prashanth Sreenivasa <[email protected]> Approved by: Robert Mustacchi <[email protected]> Author: Brad Lewis <[email protected]> Modified: stable/12/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c ============================================================================== --- stable/12/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c Tue Jun 11 14:17:05 2019 (r348907) +++ stable/12/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c Tue Jun 11 14:18:04 2019 (r348908) @@ -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 _______________________________________________ [email protected] mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "[email protected]"
