aboutsummaryrefslogtreecommitdiffstats
path: root/module/zfs/zfs_replay.c
diff options
context:
space:
mode:
authorChunwei Chen <[email protected]>2019-08-28 10:42:02 -0700
committerBrian Behlendorf <[email protected]>2019-08-28 10:42:02 -0700
commit035e96118bc9a7cbf435dd17dda507b870fcf6e6 (patch)
tree71cb2c19bd850251f28966a37e7ce148a65a513b /module/zfs/zfs_replay.c
parent9c9dcd6e04ae7a868efafe4447bdbe67ae25a6da (diff)
Fix zil replay panic when TX_REMOVE followed by TX_CREATE
If TX_REMOVE is followed by TX_CREATE on the same object id, we need to make sure the object removal is completely finished before creation. The current implementation relies on dnode_hold_impl with DNODE_MUST_BE_ALLOCATED returning ENOENT. While this check seems to work fine before, in current version it does not guarantee the object removal is completed. We fix this by checking if DNODE_MUST_BE_FREE returns successful instead. Also add test and remove dead code in dnode_hold_impl. Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Tom Caputi <[email protected]> Signed-off-by: Chunwei Chen <[email protected]> Closes #7151 Closes #8910 Closes #9123 Closes #9145
Diffstat (limited to 'module/zfs/zfs_replay.c')
-rw-r--r--module/zfs/zfs_replay.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/module/zfs/zfs_replay.c b/module/zfs/zfs_replay.c
index 144381769..7dea85bb6 100644
--- a/module/zfs/zfs_replay.c
+++ b/module/zfs/zfs_replay.c
@@ -337,8 +337,8 @@ zfs_replay_create_acl(void *arg1, void *arg2, boolean_t byteswap)
xva.xva_vattr.va_nblocks = lr->lr_gen;
xva.xva_vattr.va_fsid = dnodesize;
- error = dmu_object_info(zfsvfs->z_os, lr->lr_foid, NULL);
- if (error != ENOENT)
+ error = dnode_try_claim(zfsvfs->z_os, objid, dnodesize >> DNODE_SHIFT);
+ if (error)
goto bail;
if (lr->lr_common.lrc_txtype & TX_CI)
@@ -473,8 +473,8 @@ zfs_replay_create(void *arg1, void *arg2, boolean_t byteswap)
xva.xva_vattr.va_nblocks = lr->lr_gen;
xva.xva_vattr.va_fsid = dnodesize;
- error = dmu_object_info(zfsvfs->z_os, objid, NULL);
- if (error != ENOENT)
+ error = dnode_try_claim(zfsvfs->z_os, objid, dnodesize >> DNODE_SHIFT);
+ if (error)
goto out;
if (lr->lr_common.lrc_txtype & TX_CI)