]> granicus.if.org Git - zfs/commit
Fix 'zpool remap' freeing race
authorBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 2 Jan 2019 19:46:04 +0000 (11:46 -0800)
committerGitHub <noreply@github.com>
Wed, 2 Jan 2019 19:46:04 +0000 (11:46 -0800)
commit65ca2c1eb9af3c3fb2d221aabc2afa5db7b0f8cc
tree6c1405e1391f99350b90fcefe41f0d279f02644f
parent06f3fc2a4b097545259935d54634c5c6f49ed20f
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
cmd/ztest/ztest.c
module/zfs/dmu.c