diff options
author | George Amanakis <[email protected]> | 2022-06-27 23:17:25 +0200 |
---|---|---|
committer | GitHub <[email protected]> | 2022-06-27 14:17:25 -0700 |
commit | 80a650b7bb04bce3aef5e4cfd1d966e3599dafd4 (patch) | |
tree | 7881ecffe3e384f5573d3eae57f41df3f3bec07b /include | |
parent | 1cd72b9c1348bbc71310fb6c3d49670362faf306 (diff) |
Avoid panic with recordsize > 128k, raw sending and no large_blocks
The current codebase does not support raw sending buffers with block
size > 128kB when large_blocks is not active. This can happen in the
codepath dsl_dataset_sync()->dmu_objset_sync()->zio_nowait() which
calls back dmu_objset_write_done()->dsl_dataset_block_born(). If
dsl_dataset_sync() completes its run before dsl_dataset_block_born() is
called, we will end up not activating some of the necessary flags, while
having blocks based on those flags written in the filesystem. A
subsequent send will then panic.
Fix this by directly deciding in dmu_objset_sync() whether these flags
need to be activated later by dsl_dataset_sync(). Instead of panicking
due to a NULL pointer dereference in dmu_dump_write() in case of a send,
print out an error message. Also during scrub verify there are no
contradicting filesystem flags.
Reviewed-by: Paul Dagnelie <[email protected]>
Signed-off-by: George Amanakis <[email protected]>
Closes #12275
Closes #12438
Diffstat (limited to 'include')
-rw-r--r-- | include/sys/dsl_dataset.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/include/sys/dsl_dataset.h b/include/sys/dsl_dataset.h index a8ca7444a..561d49dac 100644 --- a/include/sys/dsl_dataset.h +++ b/include/sys/dsl_dataset.h @@ -373,6 +373,7 @@ boolean_t dsl_dataset_modified_since_snap(dsl_dataset_t *ds, void dsl_dataset_sync(dsl_dataset_t *ds, zio_t *zio, dmu_tx_t *tx); void dsl_dataset_sync_done(dsl_dataset_t *ds, dmu_tx_t *tx); +void dsl_dataset_feature_set_activation(const blkptr_t *bp, dsl_dataset_t *ds); void dsl_dataset_block_born(dsl_dataset_t *ds, const blkptr_t *bp, dmu_tx_t *tx); int dsl_dataset_block_kill(dsl_dataset_t *ds, const blkptr_t *bp, |