From 8b65c157b4241f05cd2f28d451cc856d929170c1 Mon Sep 17 00:00:00 2001 From: Andrew Innes Date: Thu, 25 Aug 2022 06:57:55 +0800 Subject: [PATCH] merge spa from upstream (#123) * Avoid dirtying the final TXGs when exporting a pool There are two codepaths than can dirty final TXGs: 1) If calling spa_export_common()->spa_unload()-> spa_unload_log_sm_flush_all() after the spa_final_txg is set, then spa_sync()->spa_flush_metaslabs() may end up dirtying the final TXGs. Then we have the following panic: Call Trace: dump_stack_lvl+0x46/0x62 spl_panic+0xea/0x102 [spl] dbuf_dirty+0xcd6/0x11b0 [zfs] zap_lockdir_impl+0x321/0x590 [zfs] zap_lockdir+0xed/0x150 [zfs] zap_update+0x69/0x250 [zfs] feature_sync+0x5f/0x190 [zfs] space_map_alloc+0x83/0xc0 [zfs] spa_generate_syncing_log_sm+0x10b/0x2f0 [zfs] spa_flush_metaslabs+0xb2/0x350 [zfs] spa_sync_iterate_to_convergence+0x15a/0x320 [zfs] spa_sync+0x2e0/0x840 [zfs] txg_sync_thread+0x2b1/0x3f0 [zfs] thread_generic_wrapper+0x62/0xa0 [spl] kthread+0x127/0x150 ret_from_fork+0x22/0x30 2) Calling vdev_*_stop_all() for a second time in spa_unload() after spa_export_common() unnecessarily delays the final TXGs beyond what spa_final_txg is set at. Fix this by performing the check and call for spa_unload_log_sm_flush_all() before the spa_final_txg is set in spa_export_common(). Also check if the spa_final_txg has already been set in spa_unload() and skip those calls in this case. Reviewed-by: Brian Behlendorf Signed-off-by: George Amanakis External-issue: https://www.illumos.org/issues/9081 Closes #13048 Closes #13098 * Add spa _os() hooks Add hooks for when spa is created, exported, activated and deactivated. Used by macOS to attach iokit, and lock kext as busy (to stop unloads). Userland, Linux, and, FreeBSD have empty stubs. Reviewed-by: Brian Behlendorf Signed-off-by: Jorgen Lundman Closes #12801 * Windows: Add spa_os() hooks use the common spa prototypes instead of the windows specific ones Signed-off-by: Andrew Innes Signed-off-by: Andrew Innes Co-authored-by: George Amanakis Co-authored-by: Jorgen Lundman --- include/os/windows/zfs/sys/zfs_context_os.h | 4 ---- module/os/windows/zfs/spa_misc_os.c | 8 ++++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/include/os/windows/zfs/sys/zfs_context_os.h b/include/os/windows/zfs/sys/zfs_context_os.h index bcb409205919..2a19883c15dd 100644 --- a/include/os/windows/zfs/sys/zfs_context_os.h +++ b/include/os/windows/zfs/sys/zfs_context_os.h @@ -195,10 +195,6 @@ extern void kx_qsort(void *array, size_t nm, size_t member_size, #define strstr kmem_strstr -void spa_create_os(void *spa); -void spa_export_os(void *spa); -void spa_activate_os(void *spa); -void spa_deactivate_os(void *spa); #define task_io_account_read(n) #define task_io_account_write(n) diff --git a/module/os/windows/zfs/spa_misc_os.c b/module/os/windows/zfs/spa_misc_os.c index d75e3cd29fa5..97c6eee4887b 100644 --- a/module/os/windows/zfs/spa_misc_os.c +++ b/module/os/windows/zfs/spa_misc_os.c @@ -54,23 +54,23 @@ spa_history_zone(void) } void -spa_create_os(void *arg) +spa_import_os(spa_t *arg) { } void -spa_export_os(void *arg) +spa_export_os(spa_t *arg) { } void -spa_activate_os(void *arg) +spa_activate_os(spa_t *arg) { atomic_inc_64(&zfs_module_busy); } void -spa_deactivate_os(void *arg) +spa_deactivate_os(spa_t *arg) { atomic_dec_64(&zfs_module_busy); }