summaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
authorNed Bass <[email protected]>2017-09-05 16:09:15 -0700
committerBrian Behlendorf <[email protected]>2017-09-05 16:09:15 -0700
commit65dcb0f67a4d72ee4e1e534703db5caacf1ec85f (patch)
treeeff9601d9162ede41c171824f2a264fe8e281246 /module
parentc8811dec7044a126650c7e2d9f3404680ae115b5 (diff)
Handle new dnode size in incremental backup stream
When receiving an incremental backup stream, call dmu_object_reclaim_dnsize() if an object's dnode size differs between the incremental source and target. Otherwise it may appear that a dnode which has shrunk is still occupying slots which are in fact free. This will cause a failure to receive new objects that should occupy the now-free slots. Add a test case to verify that an incremental stream containing objects with changed dnode sizes can be received without error. This test case fails without this change. Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Ned Bass <[email protected]> Closes #6366 Closes #6576
Diffstat (limited to 'module')
-rw-r--r--module/zfs/dmu_send.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/module/zfs/dmu_send.c b/module/zfs/dmu_send.c
index 359ef99d3..882926b75 100644
--- a/module/zfs/dmu_send.c
+++ b/module/zfs/dmu_send.c
@@ -2482,11 +2482,13 @@ receive_object(struct receive_writer_arg *rwa, struct drr_object *drro,
} else if (drro->drr_type != doi.doi_type ||
drro->drr_blksz != doi.doi_data_block_size ||
drro->drr_bonustype != doi.doi_bonus_type ||
- drro->drr_bonuslen != doi.doi_bonus_size) {
+ drro->drr_bonuslen != doi.doi_bonus_size ||
+ drro->drr_dn_slots != (doi.doi_dnodesize >> DNODE_SHIFT)) {
/* currently allocated, but with different properties */
- err = dmu_object_reclaim(rwa->os, drro->drr_object,
+ err = dmu_object_reclaim_dnsize(rwa->os, drro->drr_object,
drro->drr_type, drro->drr_blksz,
- drro->drr_bonustype, drro->drr_bonuslen, tx);
+ drro->drr_bonustype, drro->drr_bonuslen,
+ drro->drr_dn_slots << DNODE_SHIFT, tx);
}
if (err != 0) {
dmu_tx_commit(tx);