mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 18:40:43 +03:00
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 <mahrens@delphix.com> Reviewed by: Tom Caputi <tcaputi@datto.com> Reviewed by: Igor Kozhukhov <igor@dilos.org> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #8215
This commit is contained in:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user