diff options
author | Brian Behlendorf <[email protected]> | 2019-01-02 11:46:04 -0800 |
---|---|---|
committer | GitHub <[email protected]> | 2019-01-02 11:46:04 -0800 |
commit | 65ca2c1eb9af3c3fb2d221aabc2afa5db7b0f8cc (patch) | |
tree | 6c1405e1391f99350b90fcefe41f0d279f02644f /cmd | |
parent | 06f3fc2a4b097545259935d54634c5c6f49ed20f (diff) |
Fix 'zpool remap' freeing race
The dmu_objset_remap_indirects_impl() logic depends on dnode_hold()
returning ENOENT for dnodes which will be freed and should be skipped.
This behavior can only be relied upon when taking a new hold and
while the caller has an open transaction. This ensures that the
open txg cannot advance and that a concurrent free will end up
in the same txg (which is critical). Relying on an existing hold
will not prevent dnode_free() from succeeding.
The solution is to take an additional dnode_hold() after assigning
the transaction. This ensures the remap will never dirty the dnode
if it was freed while we were waiting in dmu_tx_assign(, TXG_WAIT).
Randomly set zfs_object_remap_one_indirect_delay_ms in ztest. This
increases the likelihood of an operation racing with the remap.
Converted from ticks to milliseconds.
Reviewed by: Matt Ahrens <[email protected]>
Reviewed by: Tom Caputi <[email protected]>
Reviewed by: Igor Kozhukhov <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Closes #8215
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/ztest/ztest.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/cmd/ztest/ztest.c b/cmd/ztest/ztest.c index 28ab0e846..f9ba9b6d0 100644 --- a/cmd/ztest/ztest.c +++ b/cmd/ztest/ztest.c @@ -215,6 +215,8 @@ extern int dmu_object_alloc_chunk_shift; extern boolean_t zfs_force_some_double_word_sm_entries; extern unsigned long zio_decompress_fail_fraction; extern unsigned long zfs_reconstruct_indirect_damage_fraction; +extern int zfs_object_remap_one_indirect_delay_ms; + static ztest_shared_opts_t *ztest_shared_opts; static ztest_shared_opts_t ztest_opts; @@ -6526,6 +6528,12 @@ ztest_resume_thread(void *arg) */ if (ztest_random(10) == 0) zfs_abd_scatter_enabled = ztest_random(2); + + /* + * Periodically inject remapping delays (10% of the time). + */ + zfs_object_remap_one_indirect_delay_ms = + ztest_random(10) == 0 ? ztest_random(1000) + 1 : 0; } thread_exit(); |