Skip to content

Commit

Permalink
Fix dnode byteswapping
Browse files Browse the repository at this point in the history
If a dnode has a spill pointer, and we use DN_SLOTS_TO_BONUSLEN() then
we will possibly include the spill pointer in the len calculation and it
will be byteswapped. Then dnode_byteswap() will carry on and swap the
spill pointer again. Fix this by using DN_MAX_BONUS_LEN() instead.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: George Amanakis <gamanakis@gmail.com>
Closes openzfs#13002 
Closes openzfs#13015
  • Loading branch information
gamanakis authored Jun 30, 2022
1 parent 2d434e8 commit 34e5423
Showing 1 changed file with 2 additions and 11 deletions.
13 changes: 2 additions & 11 deletions module/zfs/dnode.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,20 +342,11 @@ dnode_byteswap(dnode_phys_t *dnp)
* dnode dnode is smaller than a regular dnode.
*/
if (dnp->dn_bonuslen != 0) {
/*
* Note that the bonus length calculated here may be
* longer than the actual bonus buffer. This is because
* we always put the bonus buffer after the last block
* pointer (instead of packing it against the end of the
* dnode buffer).
*/
int off = (dnp->dn_nblkptr-1) * sizeof (blkptr_t);
int slots = dnp->dn_extra_slots + 1;
size_t len = DN_SLOTS_TO_BONUSLEN(slots) - off;
dmu_object_byteswap_t byteswap;
ASSERT(DMU_OT_IS_VALID(dnp->dn_bonustype));
byteswap = DMU_OT_BYTESWAP(dnp->dn_bonustype);
dmu_ot_byteswap[byteswap].ob_func(dnp->dn_bonus + off, len);
dmu_ot_byteswap[byteswap].ob_func(DN_BONUS(dnp),
DN_MAX_BONUS_LEN(dnp));
}

/* Swap SPILL block if we have one */
Expand Down

0 comments on commit 34e5423

Please sign in to comment.