During pool export flush the ARC asynchronously

This also includes removing L2 vdevs asynchronously.

This commit also guarantees that spa_load_guid is unique.

The zpool reguid feature introduced the spa_load_guid, which is a
transient value used for runtime identification purposes in the ARC.
This value is not the same as the spa's persistent pool guid.

However, the value is seeded from spa_generate_load_guid() which
does not check for uniqueness against the spa_load_guid from other
pools.  Although extremely rare, you can end up with two different
pools sharing the same spa_load_guid value! So we guarantee that
the value is always unique and additionally not still in use by an
async arc flush task.

Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Reviewed-by: Allan Jude <allan@klarasystems.com>
Signed-off-by: Don Brady <don.brady@klarasystems.com>
Closes #16215
This commit is contained in:
Don Brady
2024-12-05 09:58:20 -07:00
committed by GitHub
parent 2507db612d
commit 44446dccdb
7 changed files with 341 additions and 82 deletions
+15 -7
View File
@@ -404,13 +404,21 @@ dsl_pool_close(dsl_pool_t *dp)
taskq_destroy(dp->dp_zil_clean_taskq);
spa_sync_tq_destroy(dp->dp_spa);
/*
* We can't set retry to TRUE since we're explicitly specifying
* a spa to flush. This is good enough; any missed buffers for
* this spa won't cause trouble, and they'll eventually fall
* out of the ARC just like any other unused buffer.
*/
arc_flush(dp->dp_spa, FALSE);
if (dp->dp_spa->spa_state == POOL_STATE_EXPORTED ||
dp->dp_spa->spa_state == POOL_STATE_DESTROYED) {
/*
* On export/destroy perform the ARC flush asynchronously.
*/
arc_flush_async(dp->dp_spa);
} else {
/*
* We can't set retry to TRUE since we're explicitly specifying
* a spa to flush. This is good enough; any missed buffers for
* this spa won't cause trouble, and they'll eventually fall
* out of the ARC just like any other unused buffer.
*/
arc_flush(dp->dp_spa, FALSE);
}
mmp_fini(dp->dp_spa);
txg_fini(dp);