Skip to content

fix: set padding bits at end of inode bitmap in compactext4#2811

Open
lox wants to merge 1 commit into
microsoft:mainfrom
lox:fix-inode-bitmap-padding
Open

fix: set padding bits at end of inode bitmap in compactext4#2811
lox wants to merge 1 commit into
microsoft:mainfrom
lox:fix-inode-bitmap-padding

Conversation

@lox

@lox lox commented Jul 8, 2026

Copy link
Copy Markdown

Description

compactext4 leaves the tail bits of each group's inode bitmap clear. ext4
convention (enforced by e2fsck) is that bitmap bits beyond the last real inode
in the block are set to 1 so allocators never treat nonexistent inodes as
free. As a result, e2fsck 1.47.x reports on any tar2ext4 output:

Padding at end of inode bitmap is not set. Fix? no

and exits 4 ("filesystem still has errors"). The image is otherwise clean.

Since bestGroupCount commonly picks an inodesPerGroup well below
maxInodesPerGroup (32768), the unset padding affects every group, not just
the last. The block bitmap already handles its analogous case (blocks absent
from the disk in the last group are marked allocated); this adds the
inode-bitmap equivalent.

Padding bits are deliberately not counted in usedInodeCount: free-inode
accounting in the group descriptors and superblock is based on
inodesPerGroup real inodes. e2fsck reports identical file counts before and
after this change.

Found by running e2fsck -f -n against tar2ext4 output while benchmarking it
against another ext4 writer implementation (e2fsck 1.47.3). Existing tests
didn't catch this because the fsck() verification helper is Linux-only and
the per-block inode-bitmap padding check only appears in recent e2fsprogs.

Repro

go build ./cmd/tar2ext4
./tar2ext4 -i rootfs.tar -o rootfs.ext4
e2fsck -f -n rootfs.ext4   # exits 4 before this change, 0 after

Changes

  • Set inode bitmap bits from inodesPerGroup to BlockSize*8 in every group
    in Writer.Close()
  • Add TestInodeBitmapPadding, which parses the superblock and group
    descriptors from the emitted image and asserts the padding bits directly
    (platform-independent, doesn't depend on the host's e2fsck version), then
    runs the existing fsck() helper

Compatibility note

This changes the emitted image bytes. Images remain deterministic (the
existing tar2ext4 determinism test passes), but dm-verity root hashes
computed over newly generated images will differ from those of images
generated before this change.

ext4 convention (enforced by e2fsck) is that inode bitmap bits beyond
the last real inode in the block are set to 1 so allocators never treat
nonexistent inodes as free. compactext4 left these tail bits clear in
every group, so e2fsck 1.47.x reports "Padding at end of inode bitmap
is not set" and exits 4 on tar2ext4 output.

The block bitmap already handles its analogous case (absent blocks in
the last group are marked allocated); this adds the inode-bitmap
equivalent. Padding bits are not counted in usedInodeCount since
free-inode accounting is based on inodesPerGroup real inodes.

Found by running e2fsck -f -n against tar2ext4 output with e2fsck
1.47.3.

Signed-off-by: Lachlan Donald <lachlan@ljd.cc>
@lox lox requested a review from a team as a code owner July 8, 2026 04:30
@lox

lox commented Jul 8, 2026

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant