summaryrefslogtreecommitdiffstats
path: root/module/zfs
diff options
context:
space:
mode:
Diffstat (limited to 'module/zfs')
-rw-r--r--module/zfs/spa_log_spacemap.c30
1 files changed, 28 insertions, 2 deletions
diff --git a/module/zfs/spa_log_spacemap.c b/module/zfs/spa_log_spacemap.c
index 5733b6c13..bb6610fe0 100644
--- a/module/zfs/spa_log_spacemap.c
+++ b/module/zfs/spa_log_spacemap.c
@@ -989,7 +989,7 @@ spa_ld_log_sm_metadata(spa_t *spa)
/* the space map ZAP doesn't exist yet */
return (0);
} else if (error != 0) {
- spa_load_failed(spa, "spa_ld_unflushed_txgs(): failed at "
+ spa_load_failed(spa, "spa_ld_log_sm_metadata(): failed at "
"zap_lookup(DMU_POOL_DIRECTORY_OBJECT) [error %d]",
error);
return (error);
@@ -998,19 +998,45 @@ spa_ld_log_sm_metadata(spa_t *spa)
zap_cursor_t zc;
zap_attribute_t za;
for (zap_cursor_init(&zc, spa_meta_objset(spa), spacemap_zap);
- zap_cursor_retrieve(&zc, &za) == 0; zap_cursor_advance(&zc)) {
+ (error = zap_cursor_retrieve(&zc, &za)) == 0;
+ zap_cursor_advance(&zc)) {
uint64_t log_txg = zfs_strtonum(za.za_name, NULL);
spa_log_sm_t *sls =
spa_log_sm_alloc(za.za_first_integer, log_txg);
avl_add(&spa->spa_sm_logs_by_txg, sls);
}
zap_cursor_fini(&zc);
+ if (error != ENOENT) {
+ spa_load_failed(spa, "spa_ld_log_sm_metadata(): failed at "
+ "zap_cursor_retrieve(spacemap_zap) [error %d]",
+ error);
+ return (error);
+ }
for (metaslab_t *m = avl_first(&spa->spa_metaslabs_by_flushed);
m; m = AVL_NEXT(&spa->spa_metaslabs_by_flushed, m)) {
spa_log_sm_t target = { .sls_txg = metaslab_unflushed_txg(m) };
spa_log_sm_t *sls = avl_find(&spa->spa_sm_logs_by_txg,
&target, NULL);
+
+ /*
+ * At this point if sls is zero it means that a bug occurred
+ * in ZFS the last time the pool was open or earlier in the
+ * import code path. In general, we would have placed a
+ * VERIFY() here or in this case just let the kernel panic
+ * with NULL pointer dereference when incrementing sls_mscount,
+ * but since this is the import code path we can be a bit more
+ * lenient. Thus, for DEBUG bits we always cause a panic, while
+ * in production we log the error and just fail the import.
+ */
+ ASSERT(sls != NULL);
+ if (sls == NULL) {
+ spa_load_failed(spa, "spa_ld_log_sm_metadata(): bug "
+ "encountered: could not find log spacemap for "
+ "TXG %ld [error %d]",
+ metaslab_unflushed_txg(m), ENOENT);
+ return (ENOENT);
+ }
sls->sls_mscount++;
}