mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +03:00
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 <behlendorf1@llnl.gov> Reviewed-by: Tom Caputi <tcaputi@datto.com> Signed-off-by: Chunwei Chen <david.chen@nutanix.com> Closes #7151 Closes #8910 Closes #9123 Closes #9145
This commit is contained in:
committed by
Brian Behlendorf
parent
9c9dcd6e04
commit
035e96118b
+2
-5
@@ -46,6 +46,7 @@ extern "C" {
|
||||
*/
|
||||
#define DNODE_MUST_BE_ALLOCATED 1
|
||||
#define DNODE_MUST_BE_FREE 2
|
||||
#define DNODE_DRY_RUN 4
|
||||
|
||||
/*
|
||||
* dnode_next_offset() flags.
|
||||
@@ -415,6 +416,7 @@ int dnode_hold_impl(struct objset *dd, uint64_t object, int flag, int dn_slots,
|
||||
boolean_t dnode_add_ref(dnode_t *dn, void *ref);
|
||||
void dnode_rele(dnode_t *dn, void *ref);
|
||||
void dnode_rele_and_unlock(dnode_t *dn, void *tag, boolean_t evicting);
|
||||
int dnode_try_claim(objset_t *os, uint64_t object, int slots);
|
||||
void dnode_setdirty(dnode_t *dn, dmu_tx_t *tx);
|
||||
void dnode_sync(dnode_t *dn, dmu_tx_t *tx);
|
||||
void dnode_allocate(dnode_t *dn, dmu_object_type_t ot, int blocksize, int ibs,
|
||||
@@ -531,11 +533,6 @@ typedef struct dnode_stats {
|
||||
* a range of dnode slots which would overflow the dnode_phys_t.
|
||||
*/
|
||||
kstat_named_t dnode_hold_free_overflow;
|
||||
/*
|
||||
* Number of times a dnode_hold(...) was attempted on a dnode
|
||||
* which had already been unlinked in an earlier txg.
|
||||
*/
|
||||
kstat_named_t dnode_hold_free_txg;
|
||||
/*
|
||||
* Number of times dnode_free_interior_slots() needed to retry
|
||||
* acquiring a slot zrl lock due to contention.
|
||||
|
||||
Reference in New Issue
Block a user