[PATCH 2/2] erofs-utils: lib: fix meta_blkaddr handling for 48-bit layout

Ajay newajay.11r at gmail.com
Fri Mar 20 03:53:22 AEDT 2026


Hi, I looked into the history of this FIXME (which was introduced in
your commit 6eae70b1 "erofs-utils: mkfs: enable directory data in the
metadata zone"). The reason sbi->meta_blkaddr must not be eagerly set
to 0 in lib/metabox.c for 48-bit layouts is due to how the relative
NID offset math works in memory before erofs_metazone_flush() resolves
the absolute block address. In erofs_fixup_meta_blkaddr(), meta_offset
is set to -bsz to avoid NID 0. To compensate, sbi->meta_blkaddr must
remain EROFS_META_NEW_ADDR (which equates to -1 block). Later, in
erofs_metazone_flush(), when the absolute metazone start block is
allocated, it does: sbi->meta_blkaddr += meta_blkaddr;
Since sbi->meta_blkaddr is -1 block, -1 + meta_blkaddr equals
meta_blkaddr - 1. This correctly offsets the -bsz byte offset so that
NID math (addr = meta_blkaddr * bsz + (nid << 5)) calculates the
correct actual block address without wasting space!
If we were to eagerly set sbi->meta_blkaddr = 0 in metabox.c, the
flush would set it to exactly meta_blkaddr, breaking the -bsz tracking
and causing the DBG_BUGON(sbi->meta_blkaddr != -1) assertion in
erofs_fixup_meta_blkaddr() to trip.
Since EROFS 48-bit layouts don't use the legacy meta_blkaddr field
anyway, leaving the in-memory variable as EROFS_META_NEW_ADDR is
mathematically required for the mkfs flush logic, while the on-disk
superblock value is correctly hardcoded to 0 in lib/super.c.
Because of this, the FIXME comment in metabox.c is actually outdated,
which is why the patch just removes the comment itself.

Let me know if this makes sense to you.
Thanks, Ajay Rajera.

On Thu, 19 Mar 2026 at 19:15, Gao Xiang <hsiangkao at linux.alibaba.com> wrote:
>
>
>
> On 2026/3/19 21:39, Ajay Rajera wrote:
> > Fix the FIXME in metabox.c by properly handling meta_blkaddr for 48-bit layouts. In erofs_writesb(), set meta_blkaddr to 0 on-disk when 48-bit layout is enabled since meta_blkaddr is encoded differently in that mode. Remove the now-resolved FIXME comment in metabox.c as the issue is addressed in super.c.
> >
> > Signed-off-by: Ajay Rajera <newajay.11r at gmail.com>
> > ---
> >   lib/metabox.c | 1 -
> >   lib/super.c   | 2 +-
> >   2 files changed, 1 insertion(+), 2 deletions(-)
> >
> > diff --git a/lib/metabox.c b/lib/metabox.c
> > index d6abd51..077f88b 100644
> > --- a/lib/metabox.c
> > +++ b/lib/metabox.c
> > @@ -62,7 +62,6 @@ int erofs_metadata_init(struct erofs_sb_info *sbi)
> >               if (ret)
> >                       goto err_free;
> >               sbi->m2gr = m2gr;
> > -             /* FIXME: sbi->meta_blkaddr should be 0 for 48-bit layouts */
>
> I don't think it's a valid patch, I need to find more clue why
> it was a FIXME.
>
> >               sbi->meta_blkaddr = EROFS_META_NEW_ADDR;
> >       }
> >
> > diff --git a/lib/super.c b/lib/super.c
> > index 088c9a0..99d2a24 100644
> > --- a/lib/super.c
> > +++ b/lib/super.c
> > @@ -209,7 +209,7 @@ int erofs_writesb(struct erofs_sb_info *sbi)
> >               .epoch     = cpu_to_le64(sbi->epoch),
> >               .build_time = cpu_to_le64(sbi->build_time),
> >               .fixed_nsec = cpu_to_le32(sbi->fixed_nsec),
> > -             .meta_blkaddr  = cpu_to_le32(sbi->meta_blkaddr),
> > +             .meta_blkaddr  = cpu_to_le32(erofs_sb_has_48bit(sbi) ? 0 : sbi->meta_blkaddr),
> >               .xattr_blkaddr = cpu_to_le32(sbi->xattr_blkaddr),
> >               .xattr_prefix_count = sbi->xattr_prefix_count,
> >               .xattr_prefix_start = cpu_to_le32(sbi->xattr_prefix_start),
>


More information about the Linux-erofs mailing list