summaryrefslogtreecommitdiffstats
path: root/cmd
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2019-01-02 11:46:04 -0800
committerGitHub <[email protected]>2019-01-02 11:46:04 -0800
commit65ca2c1eb9af3c3fb2d221aabc2afa5db7b0f8cc (patch)
tree6c1405e1391f99350b90fcefe41f0d279f02644f /cmd
parent06f3fc2a4b097545259935d54634c5c6f49ed20f (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.c8
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();