From 34e5423f83202653bd6b153577187f6ed943c157 Mon Sep 17 00:00:00 2001 From: George Amanakis Date: Thu, 30 Jun 2022 02:06:16 +0200 Subject: [PATCH] Fix dnode byteswapping 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 Signed-off-by: George Amanakis Closes #13002 Closes #13015 --- module/zfs/dnode.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/module/zfs/dnode.c b/module/zfs/dnode.c index 39e9ca1b8..7157d8c8a 100644 --- a/module/zfs/dnode.c +++ b/module/zfs/dnode.c @@ -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 */