]> git.proxmox.com Git - mirror_zfs.git/commitdiff
Fix dnode byteswapping
authorGeorge Amanakis <gamanakis@gmail.com>
Thu, 30 Jun 2022 00:06:16 +0000 (02:06 +0200)
committerGitHub <noreply@github.com>
Thu, 30 Jun 2022 00:06:16 +0000 (17:06 -0700)
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 #13002
Closes #13015

module/zfs/dnode.c

index 39e9ca1b8161fc0cc36d7f629b59cf2003b63c85..7157d8c8a920d57bf7880d413309801603e0c4ff 100644 (file)
@@ -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 */