The branch main has been updated by tsoome:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=6e25c4321cd5fcf54fa63f20cb787713245a87a8

commit 6e25c4321cd5fcf54fa63f20cb787713245a87a8
Author:     Toomas Soome <tso...@freebsd.org>
AuthorDate: 2025-08-15 04:55:49 +0000
Commit:     Toomas Soome <tso...@freebsd.org>
CommitDate: 2025-08-15 04:55:49 +0000

    makefs: zfs uberblock location is calculated wrong
    
    The shift used to calculate uberblock location depends both
    on minimum size (UBERBLOCK_SHIFT) and MAX_UBERBLOCK_SHIFT.
    Since makefs defaults to use ashift 12, it incidentally
    does get the correct size, but ashift 9 does not work with
    current code.
    
    Reviewed by:    markj
    Differential Revision:  https://reviews.freebsd.org/D51860
---
 sys/cddl/boot/zfs/zfsimpl.h | 6 ++++++
 usr.sbin/makefs/zfs.c       | 2 +-
 usr.sbin/makefs/zfs/vdev.c  | 2 +-
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/sys/cddl/boot/zfs/zfsimpl.h b/sys/cddl/boot/zfs/zfsimpl.h
index 83d964360343..915aeeda3c9e 100644
--- a/sys/cddl/boot/zfs/zfsimpl.h
+++ b/sys/cddl/boot/zfs/zfsimpl.h
@@ -536,6 +536,12 @@ typedef struct zio_gbh {
        offsetof(vdev_label_t, vl_uberblock[(n) << VDEV_UBERBLOCK_SHIFT(vd)])
 #define        VDEV_UBERBLOCK_SIZE(vd)         (1ULL << 
VDEV_UBERBLOCK_SHIFT(vd))
 
+#define        ASHIFT_UBERBLOCK_SHIFT(ashift)  \
+       MIN(MAX(ashift, UBERBLOCK_SHIFT), \
+       MAX_UBERBLOCK_SHIFT)
+#define        ASHIFT_UBERBLOCK_SIZE(ashift) \
+       (1ULL << ASHIFT_UBERBLOCK_SHIFT(ashift))
+
 typedef struct vdev_phys {
        char            vp_nvlist[VDEV_PHYS_SIZE - sizeof (zio_eck_t)];
        zio_eck_t       vp_zbt;
diff --git a/usr.sbin/makefs/zfs.c b/usr.sbin/makefs/zfs.c
index 8d50c450541b..e33a182e5c8f 100644
--- a/usr.sbin/makefs/zfs.c
+++ b/usr.sbin/makefs/zfs.c
@@ -596,7 +596,7 @@ pool_labels_write(zfs_opt_t *zfs)
         * checksum is calculated in vdev_label_write().
         */
        for (size_t uoff = 0; uoff < sizeof(label->vl_uberblock);
-           uoff += (1 << zfs->ashift)) {
+           uoff += ASHIFT_UBERBLOCK_SIZE(zfs->ashift)) {
                ub = (uberblock_t *)(&label->vl_uberblock[0] + uoff);
                ub->ub_magic = UBERBLOCK_MAGIC;
                ub->ub_version = SPA_VERSION;
diff --git a/usr.sbin/makefs/zfs/vdev.c b/usr.sbin/makefs/zfs/vdev.c
index afcce402cb13..a2423e180ca3 100644
--- a/usr.sbin/makefs/zfs/vdev.c
+++ b/usr.sbin/makefs/zfs/vdev.c
@@ -200,7 +200,7 @@ vdev_label_write(zfs_opt_t *zfs, int ind, const 
vdev_label_t *labelp)
         * per sector; for example, with an ashift of 12 we end up with
         * 128KB/4KB=32 copies of the uberblock in the ring.
         */
-       blksz = 1 << zfs->ashift;
+       blksz = ASHIFT_UBERBLOCK_SIZE(zfs->ashift);
        assert(sizeof(label->vl_uberblock) % blksz == 0);
        for (size_t roff = 0; roff < sizeof(label->vl_uberblock);
            roff += blksz) {

Reply via email to