Skip to content

Commit 15c3547

Browse files
gamanakisTulsiJain
authored andcommitted
Improve zpool status output, list all affected datasets
Currently, determining which datasets are affected by corruption is a manual process. The primary difficulty in reporting the list of affected snapshots is that since the error was initially found, the snapshot where the error originally occurred in, may have been deleted. To solve this issue, we add the ID of the head dataset of the original snapshot which the error was detected in, to the stored error report. Then any time a filesystem is deleted, the errors associated with it are deleted as well. Any time a clone promote occurs, we modify reports associated with the original head to refer to the new head. The stored error reports are identified by this head ID, the birth time of the block which the error occurred in, as well as some information about the error itself are also stored. Once this information is stored, we can find the set of datasets affected by an error by walking back the list of snapshots in the given head until we find one with the appropriate birth txg, and then traverse through the snapshots of the clone family, terminating a branch if the block was replaced in a given snapshot. Then we report this information back to libzfs, and to the zpool status command, where it is displayed as follows: pool: test state: ONLINE status: One or more devices has experienced an error resulting in data corruption. Applications may be affected. action: Restore the file in question if possible. Otherwise restore the entire pool from backup. see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-8A scan: scrub repaired 0B in 00:00:00 with 800 errors on Fri Dec 3 08:27:57 2021 config: NAME STATE READ WRITE CKSUM test ONLINE 0 0 0 sdb ONLINE 0 0 1.58K errors: Permanent errors have been detected in the following files: test@1:/test.0.0 /test/test.0.0 /test/1clone/test.0.0 A new feature flag is introduced to mark the presence of this change, as well as promotion and backwards compatibility logic. This is an updated version of openzfs#9175. Rebase required fixing the tests, updating the ABI of libzfs, updating the man pages, fixing bugs, fixing the error returns, and updating the old on-disk error logs to the new format when activating the feature. Reviewed-by: Matthew Ahrens <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Mark Maybee <[email protected]> Reviewed-by: Tony Hutter <[email protected]> Co-authored-by: TulsiJain <[email protected]> Signed-off-by: George Amanakis <[email protected]> Closes openzfs#9175 Closes openzfs#12812
1 parent eee59f7 commit 15c3547

File tree

21 files changed

+1219
-194
lines changed

21 files changed

+1219
-194
lines changed

include/sys/dsl_dataset.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,9 @@ boolean_t dsl_dataset_get_uint64_array_feature(dsl_dataset_t *ds,
487487
void dsl_dataset_activate_redaction(dsl_dataset_t *ds, uint64_t *redact_snaps,
488488
uint64_t num_redact_snaps, dmu_tx_t *tx);
489489

490+
int dsl_dataset_oldest_snapshot(spa_t *spa, uint64_t head_ds, uint64_t min_txg,
491+
uint64_t *oldest_dsobj);
492+
490493
#ifdef ZFS_DEBUG
491494
#define dprintf_ds(ds, fmt, ...) do { \
492495
if (zfs_flags & ZFS_DEBUG_DPRINTF) { \

include/sys/spa.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1144,11 +1144,17 @@ extern void zfs_post_remove(spa_t *spa, vdev_t *vd);
11441144
extern void zfs_post_state_change(spa_t *spa, vdev_t *vd, uint64_t laststate);
11451145
extern void zfs_post_autoreplace(spa_t *spa, vdev_t *vd);
11461146
extern uint64_t spa_get_errlog_size(spa_t *spa);
1147-
extern int spa_get_errlog(spa_t *spa, void *uaddr, size_t *count);
1147+
extern int spa_get_errlog(spa_t *spa, void *uaddr, uint64_t *count);
11481148
extern void spa_errlog_rotate(spa_t *spa);
11491149
extern void spa_errlog_drain(spa_t *spa);
11501150
extern void spa_errlog_sync(spa_t *spa, uint64_t txg);
11511151
extern void spa_get_errlists(spa_t *spa, avl_tree_t *last, avl_tree_t *scrub);
1152+
extern void spa_delete_dataset_errlog(spa_t *spa, uint64_t ds, dmu_tx_t *tx);
1153+
extern void spa_swap_errlog(spa_t *spa, uint64_t new_head_ds,
1154+
uint64_t old_head_ds, dmu_tx_t *tx);
1155+
extern void sync_error_list(spa_t *spa, avl_tree_t *t, uint64_t *obj,
1156+
dmu_tx_t *tx);
1157+
extern void spa_upgrade_errlog(spa_t *spa, dmu_tx_t *tx);
11521158

11531159
/* vdev cache */
11541160
extern void vdev_cache_stat_init(void);

include/sys/zio.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,13 @@ extern const char *const zio_type_name[ZIO_TYPES];
283283
* Note: this structure is passed between userland and the kernel, and is
284284
* stored on disk (by virtue of being incorporated into other on-disk
285285
* structures, e.g. dsl_scan_phys_t).
286+
*
287+
* If the head_errlog feature is enabled a different on-disk format for error
288+
* logs is used. This introduces the use of an error bookmark, a four-tuple
289+
* <object, level, blkid, birth> that uniquely identifies any error block
290+
* in the pool. The birth transaction group is used to track whether the block
291+
* has been overwritten by newer data or added to a snapshot since its marking
292+
* as an error.
286293
*/
287294
struct zbookmark_phys {
288295
uint64_t zb_objset;
@@ -291,6 +298,13 @@ struct zbookmark_phys {
291298
uint64_t zb_blkid;
292299
};
293300

301+
typedef struct zbookmark_err_phys {
302+
uint64_t zb_object;
303+
int64_t zb_level;
304+
uint64_t zb_blkid;
305+
uint64_t zb_birth;
306+
} zbookmark_err_phys_t;
307+
294308
#define SET_BOOKMARK(zb, objset, object, level, blkid) \
295309
{ \
296310
(zb)->zb_objset = objset; \

include/zfeature_common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ typedef enum spa_feature {
7676
SPA_FEATURE_ZSTD_COMPRESS,
7777
SPA_FEATURE_DRAID,
7878
SPA_FEATURE_ZILSAXATTR,
79+
SPA_FEATURE_HEAD_ERRLOG,
7980
SPA_FEATURES
8081
} spa_feature_t;
8182

lib/libnvpair/libnvpair.abi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2794,7 +2794,7 @@
27942794
</abi-instr>
27952795
<abi-instr address-size='64' path='assert.c' language='LANG_C99'>
27962796
<function-decl name='libspl_set_assert_ok' mangled-name='libspl_set_assert_ok' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libspl_set_assert_ok'>
2797-
<parameter type-id='f58c8277' name='val'/>
2797+
<parameter type-id='c19b74c3' name='val'/>
27982798
<return type-id='48b5725f'/>
27992799
</function-decl>
28002800
<function-decl name='libspl_assertf' mangled-name='libspl_assertf' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='libspl_assertf'>

lib/libuutil/libuutil.abi

Lines changed: 94 additions & 99 deletions
Large diffs are not rendered by default.

lib/libzfs/libzfs.abi

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@
596596
<elf-symbol name='fletcher_4_superscalar4_ops' size='64' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
597597
<elf-symbol name='fletcher_4_superscalar_ops' size='64' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
598598
<elf-symbol name='libzfs_config_ops' size='16' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
599-
<elf-symbol name='spa_feature_table' size='1960' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
599+
<elf-symbol name='spa_feature_table' size='2016' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
600600
<elf-symbol name='zfeature_checks_disable' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
601601
<elf-symbol name='zfs_deleg_perm_tab' size='512' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
602602
<elf-symbol name='zfs_history_event_names' size='328' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@@ -1855,8 +1855,8 @@
18551855
</function-decl>
18561856
</abi-instr>
18571857
<abi-instr address-size='64' path='../../module/zcommon/zfeature_common.c' language='LANG_C99'>
1858-
<array-type-def dimensions='1' type-id='83f29ca2' size-in-bits='15680' id='9d60dcc5'>
1859-
<subrange length='35' type-id='7359adad' id='6e6845b5'/>
1858+
<array-type-def dimensions='1' type-id='83f29ca2' size-in-bits='16128' id='9d5e9e2e'>
1859+
<subrange length='36' type-id='7359adad' id='ae666bde'/>
18601860
</array-type-def>
18611861
<enum-decl name='spa_feature' id='33ecb627'>
18621862
<underlying-type type-id='9cac1fee'/>
@@ -1896,7 +1896,8 @@
18961896
<enumerator name='SPA_FEATURE_ZSTD_COMPRESS' value='32'/>
18971897
<enumerator name='SPA_FEATURE_DRAID' value='33'/>
18981898
<enumerator name='SPA_FEATURE_ZILSAXATTR' value='34'/>
1899-
<enumerator name='SPA_FEATURES' value='35'/>
1899+
<enumerator name='SPA_FEATURE_HEAD_ERRLOG' value='35'/>
1900+
<enumerator name='SPA_FEATURES' value='36'/>
19001901
</enum-decl>
19011902
<typedef-decl name='spa_feature_t' type-id='33ecb627' id='d6618c78'/>
19021903
<enum-decl name='zfeature_flags' id='6db816a4'>
@@ -1954,7 +1955,7 @@
19541955
<qualified-type-def type-id='3eee3342' const='yes' id='0c1d5bbb'/>
19551956
<pointer-type-def type-id='0c1d5bbb' size-in-bits='64' id='a3372543'/>
19561957
<pointer-type-def type-id='d6618c78' size-in-bits='64' id='a8425263'/>
1957-
<var-decl name='spa_feature_table' type-id='9d60dcc5' mangled-name='spa_feature_table' visibility='default' elf-symbol-id='spa_feature_table'/>
1958+
<var-decl name='spa_feature_table' type-id='9d5e9e2e' mangled-name='spa_feature_table' visibility='default' elf-symbol-id='spa_feature_table'/>
19581959
<var-decl name='zfeature_checks_disable' type-id='c19b74c3' mangled-name='zfeature_checks_disable' visibility='default' elf-symbol-id='zfeature_checks_disable'/>
19591960
<function-decl name='zfeature_is_valid_guid' mangled-name='zfeature_is_valid_guid' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfeature_is_valid_guid'>
19601961
<parameter type-id='80f4b756' name='name'/>

lib/libzfsbootenv/libzfsbootenv.abi

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
<dependency name='libc.so.6'/>
66
</elf-needed>
77
<elf-function-symbols>
8-
<elf-symbol name='_fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
9-
<elf-symbol name='_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
108
<elf-symbol name='lzbe_add_pair' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
119
<elf-symbol name='lzbe_bootenv_print' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
1210
<elf-symbol name='lzbe_get_boot_device' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@@ -20,6 +18,7 @@
2018
<type-decl name='char' size-in-bits='8' id='a84c031d'/>
2119
<type-decl name='int' size-in-bits='32' id='95e97e5e'/>
2220
<type-decl name='unnamed-enum-underlying-type-32' is-anonymous='yes' size-in-bits='32' alignment-in-bits='32' id='9cac1fee'/>
21+
<type-decl name='void' id='48b5725f'/>
2322
<enum-decl name='lzbe_flags' id='2b77720b'>
2423
<underlying-type type-id='9cac1fee'/>
2524
<enumerator name='lzbe_add' value='0'/>
@@ -84,21 +83,16 @@
8483
<array-type-def dimensions='1' type-id='a84c031d' size-in-bits='160' id='664ac0b7'>
8584
<subrange length='20' type-id='7359adad' id='fdca39cf'/>
8685
</array-type-def>
86+
<class-decl name='_IO_codecvt' is-struct='yes' visibility='default' is-declaration-only='yes' id='a4036571'/>
87+
<class-decl name='_IO_marker' is-struct='yes' visibility='default' is-declaration-only='yes' id='010ae0b9'/>
88+
<class-decl name='_IO_wide_data' is-struct='yes' visibility='default' is-declaration-only='yes' id='79bd3751'/>
8789
<type-decl name='long int' size-in-bits='64' id='bd54fe1a'/>
8890
<type-decl name='signed char' size-in-bits='8' id='28577a57'/>
8991
<type-decl name='unsigned short int' size-in-bits='16' id='8efea9e5'/>
92+
<typedef-decl name='__off_t' type-id='bd54fe1a' id='79989e9c'/>
93+
<typedef-decl name='__off64_t' type-id='bd54fe1a' id='724e4de6'/>
94+
<typedef-decl name='FILE' type-id='ec1ed955' id='aa12d1ba'/>
9095
<typedef-decl name='_IO_lock_t' type-id='48b5725f' id='bb4788fa'/>
91-
<class-decl name='_IO_marker' size-in-bits='192' is-struct='yes' visibility='default' id='010ae0b9'>
92-
<data-member access='public' layout-offset-in-bits='0'>
93-
<var-decl name='_next' type-id='e4c6fa61' visibility='default'/>
94-
</data-member>
95-
<data-member access='public' layout-offset-in-bits='64'>
96-
<var-decl name='_sbuf' type-id='dca988a5' visibility='default'/>
97-
</data-member>
98-
<data-member access='public' layout-offset-in-bits='128'>
99-
<var-decl name='_pos' type-id='95e97e5e' visibility='default'/>
100-
</data-member>
101-
</class-decl>
10296
<class-decl name='_IO_FILE' size-in-bits='1728' is-struct='yes' visibility='default' id='ec1ed955'>
10397
<data-member access='public' layout-offset-in-bits='0'>
10498
<var-decl name='_flags' type-id='95e97e5e' visibility='default'/>
@@ -167,16 +161,16 @@
167161
<var-decl name='_offset' type-id='724e4de6' visibility='default'/>
168162
</data-member>
169163
<data-member access='public' layout-offset-in-bits='1216'>
170-
<var-decl name='__pad1' type-id='eaa32e2f' visibility='default'/>
164+
<var-decl name='_codecvt' type-id='570f8c59' visibility='default'/>
171165
</data-member>
172166
<data-member access='public' layout-offset-in-bits='1280'>
173-
<var-decl name='__pad2' type-id='eaa32e2f' visibility='default'/>
167+
<var-decl name='_wide_data' type-id='c65a1f29' visibility='default'/>
174168
</data-member>
175169
<data-member access='public' layout-offset-in-bits='1344'>
176-
<var-decl name='__pad3' type-id='eaa32e2f' visibility='default'/>
170+
<var-decl name='_freeres_list' type-id='dca988a5' visibility='default'/>
177171
</data-member>
178172
<data-member access='public' layout-offset-in-bits='1408'>
179-
<var-decl name='__pad4' type-id='eaa32e2f' visibility='default'/>
173+
<var-decl name='_freeres_buf' type-id='eaa32e2f' visibility='default'/>
180174
</data-member>
181175
<data-member access='public' layout-offset-in-bits='1472'>
182176
<var-decl name='__pad5' type-id='b59d7dce' visibility='default'/>
@@ -188,19 +182,20 @@
188182
<var-decl name='_unused2' type-id='664ac0b7' visibility='default'/>
189183
</data-member>
190184
</class-decl>
191-
<typedef-decl name='__off_t' type-id='bd54fe1a' id='79989e9c'/>
192-
<typedef-decl name='__off64_t' type-id='bd54fe1a' id='724e4de6'/>
193-
<typedef-decl name='FILE' type-id='ec1ed955' id='aa12d1ba'/>
194185
<pointer-type-def type-id='aa12d1ba' size-in-bits='64' id='822cd80b'/>
195186
<pointer-type-def type-id='ec1ed955' size-in-bits='64' id='dca988a5'/>
187+
<pointer-type-def type-id='a4036571' size-in-bits='64' id='570f8c59'/>
196188
<pointer-type-def type-id='bb4788fa' size-in-bits='64' id='cecf4ea7'/>
197189
<pointer-type-def type-id='010ae0b9' size-in-bits='64' id='e4c6fa61'/>
190+
<pointer-type-def type-id='79bd3751' size-in-bits='64' id='c65a1f29'/>
191+
<class-decl name='_IO_codecvt' is-struct='yes' visibility='default' is-declaration-only='yes' id='a4036571'/>
192+
<class-decl name='_IO_marker' is-struct='yes' visibility='default' is-declaration-only='yes' id='010ae0b9'/>
193+
<class-decl name='_IO_wide_data' is-struct='yes' visibility='default' is-declaration-only='yes' id='79bd3751'/>
198194
<function-decl name='lzbe_bootenv_print' mangled-name='lzbe_bootenv_print' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='lzbe_bootenv_print'>
199195
<parameter type-id='80f4b756' name='pool'/>
200196
<parameter type-id='80f4b756' name='nvlist'/>
201197
<parameter type-id='822cd80b' name='of'/>
202198
<return type-id='95e97e5e'/>
203199
</function-decl>
204-
<type-decl name='void' id='48b5725f'/>
205200
</abi-instr>
206201
</abi-corpus>

man/man4/zfs.4

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,13 @@ If we have less than this amount of free space,
454454
most ZPL operations (e.g. write, create) will return
455455
.Sy ENOSPC .
456456
.
457+
.It Sy spa_upgrade_errlog_limit Ns = Ns Sy 0 Pq uint
458+
Limits the number of on-disk error log entries that will be converted to the
459+
new format when enabling the
460+
.Sy head_errlog
461+
feature.
462+
The default is to convert all log entries.
463+
.
457464
.It Sy vdev_removal_max_span Ns = Ns Sy 32768 Ns B Po 32kB Pc Pq int
458465
During top-level vdev removal, chunks of data are copied from the vdev
459466
which may include free space in order to trade bandwidth for IOPS.

man/man7/zpool-features.7

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,17 @@ once either of the limit properties has been set on a dataset
507507
and will never return to being
508508
.Sy enabled .
509509
.
510+
.feature com.delphix head_errlog no
511+
This feature enables the upgraded version of errlog, which required an on-disk
512+
error log format change.
513+
Now the error log of each head dataset is stored separately in the zap object
514+
and keyed by the head id.
515+
With this feature enabled, every dataset affected by an error block is listed
516+
in the output of
517+
.Nm zpool Cm status .
518+
.Pp
519+
\*[instant-never]
520+
.
510521
.feature com.delphix hole_birth no enabled_txg
511522
This feature has/had bugs, the result of which is that, if you do a
512523
.Nm zfs Cm send Fl i

module/zcommon/zfeature_common.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,7 @@ zpool_feature_init(void)
696696
ZFEATURE_FLAG_MOS, ZFEATURE_TYPE_BOOLEAN, NULL, sfeatures);
697697

698698
{
699+
699700
static const spa_feature_t zilsaxattr_deps[] = {
700701
SPA_FEATURE_EXTENSIBLE_DATASET,
701702
SPA_FEATURE_NONE
@@ -707,6 +708,12 @@ zpool_feature_init(void)
707708
ZFEATURE_TYPE_BOOLEAN, zilsaxattr_deps, sfeatures);
708709
}
709710

711+
zfeature_register(SPA_FEATURE_HEAD_ERRLOG,
712+
"com.delphix:head_errlog", "head_errlog",
713+
"Support for per-dataset on-disk error logs.",
714+
ZFEATURE_FLAG_ACTIVATE_ON_ENABLE, ZFEATURE_TYPE_BOOLEAN, NULL,
715+
sfeatures);
716+
710717
zfs_mod_list_supported_free(sfeatures);
711718
}
712719

module/zfs/dsl_dataset.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3708,6 +3708,15 @@ dsl_dataset_promote_sync(void *arg, dmu_tx_t *tx)
37083708

37093709
dsl_dir_rele(odd, FTAG);
37103710
promote_rele(ddpa, FTAG);
3711+
3712+
/*
3713+
* Transfer common error blocks from old head to new head.
3714+
*/
3715+
if (spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_HEAD_ERRLOG)) {
3716+
uint64_t old_head = origin_head->ds_object;
3717+
uint64_t new_head = hds->ds_object;
3718+
spa_swap_errlog(dp->dp_spa, new_head, old_head, tx);
3719+
}
37113720
}
37123721

37133722
/*
@@ -4924,6 +4933,37 @@ dsl_dataset_activate_redaction(dsl_dataset_t *ds, uint64_t *redact_snaps,
49244933
ds->ds_feature[SPA_FEATURE_REDACTED_DATASETS] = ftuaa;
49254934
}
49264935

4936+
/*
4937+
* Find and return (in *oldest_dsobj) the oldest snapshot of the dsobj
4938+
* dataset whose birth time is >= min_txg.
4939+
*/
4940+
int
4941+
dsl_dataset_oldest_snapshot(spa_t *spa, uint64_t head_ds, uint64_t min_txg,
4942+
uint64_t *oldest_dsobj)
4943+
{
4944+
dsl_dataset_t *ds;
4945+
dsl_pool_t *dp = spa->spa_dsl_pool;
4946+
4947+
int error = dsl_dataset_hold_obj(dp, head_ds, FTAG, &ds);
4948+
if (error != 0)
4949+
return (error);
4950+
4951+
uint64_t prev_obj = dsl_dataset_phys(ds)->ds_prev_snap_obj;
4952+
uint64_t prev_obj_txg = dsl_dataset_phys(ds)->ds_prev_snap_txg;
4953+
4954+
while (prev_obj != 0 && min_txg < prev_obj_txg) {
4955+
dsl_dataset_rele(ds, FTAG);
4956+
if ((error = dsl_dataset_hold_obj(dp, prev_obj,
4957+
FTAG, &ds)) != 0)
4958+
return (error);
4959+
prev_obj_txg = dsl_dataset_phys(ds)->ds_prev_snap_txg;
4960+
prev_obj = dsl_dataset_phys(ds)->ds_prev_snap_obj;
4961+
}
4962+
*oldest_dsobj = ds->ds_object;
4963+
dsl_dataset_rele(ds, FTAG);
4964+
return (0);
4965+
}
4966+
49274967
#if defined(_LP64)
49284968
#define RECORDSIZE_PERM ZMOD_RW
49294969
#else

module/zfs/dsl_destroy.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,6 +1153,9 @@ dsl_destroy_head_sync_impl(dsl_dataset_t *ds, dmu_tx_t *tx)
11531153
dsl_destroy_snapshot_sync_impl(prev, B_FALSE, tx);
11541154
dsl_dataset_rele(prev, FTAG);
11551155
}
1156+
/* Delete errlog. */
1157+
if (spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_HEAD_ERRLOG))
1158+
spa_delete_dataset_errlog(dp->dp_spa, ds->ds_object, tx);
11561159
}
11571160

11581161
void

0 commit comments

Comments
 (0)