diff options
Diffstat (limited to 'module')
-rw-r--r-- | module/zfs/arc.c | 2 | ||||
-rw-r--r-- | module/zfs/dmu_objset.c | 3 | ||||
-rw-r--r-- | module/zfs/mmp.c | 3 | ||||
-rw-r--r-- | module/zfs/spa.c | 6 | ||||
-rw-r--r-- | module/zfs/zio.c | 67 |
5 files changed, 52 insertions, 29 deletions
diff --git a/module/zfs/arc.c b/module/zfs/arc.c index 8fa8c91ac..3df53d2db 100644 --- a/module/zfs/arc.c +++ b/module/zfs/arc.c @@ -8396,7 +8396,7 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz) mutex_exit(hash_lock); - (void) zio_nowait(wzio); + zio_nowait(wzio); } multilist_sublist_unlock(mls); diff --git a/module/zfs/dmu_objset.c b/module/zfs/dmu_objset.c index 9f9eb1e01..a91ecb640 100644 --- a/module/zfs/dmu_objset.c +++ b/module/zfs/dmu_objset.c @@ -1714,8 +1714,7 @@ dmu_objset_sync(objset_t *os, zio_t *pio, dmu_tx_t *tx) while ((dr = list_head(list)) != NULL) { ASSERT0(dr->dr_dbuf->db_level); list_remove(list, dr); - if (dr->dr_zio) - zio_nowait(dr->dr_zio); + zio_nowait(dr->dr_zio); } /* Enable dnode backfill if enough objects have been freed. */ diff --git a/module/zfs/mmp.c b/module/zfs/mmp.c index f1a30f877..e1e468557 100644 --- a/module/zfs/mmp.c +++ b/module/zfs/mmp.c @@ -678,8 +678,7 @@ mmp_thread(void *arg) } /* Outstanding writes are allowed to complete. */ - if (mmp->mmp_zio_root) - zio_wait(mmp->mmp_zio_root); + zio_wait(mmp->mmp_zio_root); mmp->mmp_zio_root = NULL; mmp_thread_exit(mmp, &mmp->mmp_thread, &cpr); diff --git a/module/zfs/spa.c b/module/zfs/spa.c index c12b20270..a6f97eb37 100644 --- a/module/zfs/spa.c +++ b/module/zfs/spa.c @@ -8125,10 +8125,10 @@ bpobj_enqueue_free_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx) static int spa_free_sync_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx) { - zio_t *zio = arg; + zio_t *pio = arg; - zio_nowait(zio_free_sync(zio, zio->io_spa, dmu_tx_get_txg(tx), bp, - zio->io_flags)); + zio_nowait(zio_free_sync(pio, pio->io_spa, dmu_tx_get_txg(tx), bp, + pio->io_flags)); return (0); } diff --git a/module/zfs/zio.c b/module/zfs/zio.c index 9dc3c830a..cbe6fc751 100644 --- a/module/zfs/zio.c +++ b/module/zfs/zio.c @@ -1194,40 +1194,46 @@ zio_free(spa_t *spa, uint64_t txg, const blkptr_t *bp) !spa_feature_is_active(spa, SPA_FEATURE_LOG_SPACEMAP))) { bplist_append(&spa->spa_free_bplist[txg & TXG_MASK], bp); } else { - VERIFY0(zio_wait(zio_free_sync(NULL, spa, txg, bp, 0))); + VERIFY3P(zio_free_sync(NULL, spa, txg, bp, 0), ==, NULL); } } +/* + * To improve performance, this function may return NULL if we were able + * to do the free immediately. This avoids the cost of creating a zio + * (and linking it to the parent, etc). + */ zio_t * zio_free_sync(zio_t *pio, spa_t *spa, uint64_t txg, const blkptr_t *bp, enum zio_flag flags) { - zio_t *zio; - enum zio_stage stage = ZIO_FREE_PIPELINE; - ASSERT(!BP_IS_HOLE(bp)); ASSERT(spa_syncing_txg(spa) == txg); if (BP_IS_EMBEDDED(bp)) - return (zio_null(pio, spa, NULL, NULL, NULL, 0)); + return (NULL); metaslab_check_free(spa, bp); arc_freed(spa, bp); dsl_scan_freed(spa, bp); - /* - * GANG and DEDUP blocks can induce a read (for the gang block header, - * or the DDT), so issue them asynchronously so that this thread is - * not tied up. - */ - if (BP_IS_GANG(bp) || BP_GET_DEDUP(bp)) - stage |= ZIO_STAGE_ISSUE_ASYNC; - - zio = zio_create(pio, spa, txg, bp, NULL, BP_GET_PSIZE(bp), - BP_GET_PSIZE(bp), NULL, NULL, ZIO_TYPE_FREE, ZIO_PRIORITY_NOW, - flags, NULL, 0, NULL, ZIO_STAGE_OPEN, stage); + if (BP_IS_GANG(bp) || BP_GET_DEDUP(bp)) { + /* + * GANG and DEDUP blocks can induce a read (for the gang block + * header, or the DDT), so issue them asynchronously so that + * this thread is not tied up. + */ + enum zio_stage stage = + ZIO_FREE_PIPELINE | ZIO_STAGE_ISSUE_ASYNC; - return (zio); + return (zio_create(pio, spa, txg, bp, NULL, BP_GET_PSIZE(bp), + BP_GET_PSIZE(bp), NULL, NULL, + ZIO_TYPE_FREE, ZIO_PRIORITY_NOW, + flags, NULL, 0, NULL, ZIO_STAGE_OPEN, stage)); + } else { + metaslab_free(spa, bp, txg, B_FALSE); + return (NULL); + } } zio_t * @@ -2165,6 +2171,15 @@ __zio_execute(zio_t *zio) int zio_wait(zio_t *zio) { + /* + * Some routines, like zio_free_sync(), may return a NULL zio + * to avoid the performance overhead of creating and then destroying + * an unneeded zio. For the callers' simplicity, we accept a NULL + * zio and ignore it. + */ + if (zio == NULL) + return (0); + long timeout = MSEC_TO_TICK(zfs_deadman_ziotime_ms); int error; @@ -2202,6 +2217,12 @@ zio_wait(zio_t *zio) void zio_nowait(zio_t *zio) { + /* + * See comment in zio_wait(). + */ + if (zio == NULL) + return; + ASSERT3P(zio->io_executor, ==, NULL); if (zio->io_child_type == ZIO_CHILD_LOGICAL && @@ -2489,8 +2510,13 @@ static zio_t * zio_free_gang(zio_t *pio, blkptr_t *bp, zio_gang_node_t *gn, abd_t *data, uint64_t offset) { - return (zio_free_sync(pio, pio->io_spa, pio->io_txg, bp, - ZIO_GANG_CHILD_FLAGS(pio))); + zio_t *zio = zio_free_sync(pio, pio->io_spa, pio->io_txg, bp, + ZIO_GANG_CHILD_FLAGS(pio)); + if (zio == NULL) { + zio = zio_null(pio, pio->io_spa, + NULL, NULL, NULL, ZIO_GANG_CHILD_FLAGS(pio)); + } + return (zio); } /* ARGSUSED */ @@ -3273,8 +3299,7 @@ zio_ddt_write(zio_t *zio) ddt_exit(ddt); - if (cio) - zio_nowait(cio); + zio_nowait(cio); return (zio); } |