Skip to content

Support partial last EXT4 block group - #717

Open
zeel2104 wants to merge 1 commit into
apple:mainfrom
zeel2104:fix-ext4-partial-last-block-group
Open

Support partial last EXT4 block group#717
zeel2104 wants to merge 1 commit into
apple:mainfrom
zeel2104:fix-ext4-partial-last-block-group

Conversation

@zeel2104

@zeel2104 zeel2104 commented May 1, 2026

Copy link
Copy Markdown

Summary

Fixes #647 by supporting a partial final EXT4 block group.

The formatter previously rounded filesystem sizes up to the next block group boundary, so a requested 160 MiB filesystem became 256 MiB. This change keeps the requested size, reports the actual filesystem block count, and marks blocks outside a short final group as used in the bitmap without counting them as filesystem blocks.

Testing

  • swift test --filter ContainerizationEXT4Tests

@dkovba
dkovba requested a review from wlan0 May 6, 2026 22:48
@zeel2104
zeel2104 force-pushed the fix-ext4-partial-last-block-group branch from dd22578 to 5c0fe36 Compare May 6, 2026 23:53
@zeel2104

zeel2104 commented May 8, 2026

Copy link
Copy Markdown
Author

@wlan0
Hi, I resolved the issue which was occurring in CI because of not signing the commit
It is ready to be reviewed again

@wlan0

wlan0 commented May 12, 2026

Copy link
Copy Markdown
Contributor

@zeel2104 thanks for the PR!

I think this still has an edge-case layout bug for very short final groups.

The new code allows any non-zero remainder in the final block group, but this loop still places the added group’s bitmap blocks at:

    group * blocksPerGroup + inodeTableSizePerGroup
    group * blocksPerGroup + inodeTableSizePerGroup + 1

For the 160 MiB case the final group has 8192 blocks, so this is fine. But for a size like 128 MiB + 4 KiB, group 1 has only 1 filesystem block. WithinodeTableSizePerGrouparound 512, the descriptor points to bitmap blocks outside s_blocks_count, and the write seeks beyond the declared filesystem/image size.

Could we either:

  1. round up only the tiny remainder case so the last group has at least inodeTableSizePerGroup + 2 blocks, or
  2. explicitly lay out the last group’s metadata somewhere valid and set the required feature bits if that depends on flex_bg-style placement?

Please add a regression test around the boundary, e.g. minDiskSize: 128.mib() + 4.kib(), checking both file size and descriptor bitmap/table locations are < superblock block count.

@wlan0 wlan0 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is still a layout bug

#717 (comment)

@dkovba dkovba left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the contribution!
Below are the test results across the size/content matrix, cross-checked with e2fsck:

Requested Size: 32KiB
Content: none
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 64MiB
Content: none
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 128MiB
Content: none
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 128MiB+4KiB
Content: none
Size: FAIL
audit.imageSize == audit.blocksCount * 4.kib() = false; audit.imageSize = 136323072; audit.blocksCount * 4.kib() = 134221824
audit.imageSize == testCase.requested = false; audit.imageSize = 136323072; testCase.requested = 134221824
e2fsck: FAIL rc=8
ext2fs_check_desc: Corrupt group descriptor: bad block for block bitmap
Note: if several inode or block bitmap blocks or part
of the inode table require relocation, you may wish to try
may lie only with the primary block group descriptors, and
----------------------------------------
Requested Size: 130MiB+8KiB
Content: none
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 160MiB
Content: none
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 256MiB
Content: none
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 1GiB
Content: none
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 4GiB
Content: none
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 63x128MiB
Content: none
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 63x128MiB+4KiB
Content: none
Size: FAIL
audit.imageSize == audit.blocksCount * 4.kib() = false; audit.imageSize = 8457822208; audit.blocksCount * 4.kib() = 8455720960
audit.imageSize == testCase.requested = false; audit.imageSize = 8457822208; testCase.requested = 8455720960
e2fsck: FAIL rc=8
ext2fs_check_desc: Corrupt group descriptor: bad block for block bitmap
Note: if several inode or block bitmap blocks or part
of the inode table require relocation, you may wish to try
may lie only with the primary block group descriptors, and
----------------------------------------
Requested Size: 8GiB
Content: none
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 16GiB
Content: none
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 160MiB
Content: 10MiB
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 128MiB
Content: 50MiB
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 160MiB
Content: 120MiB
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 160MiB
Content: 124MiB
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 160MiB
Content: 126MiB
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 256MiB
Content: 130MiB
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 1GiB
Content: 200MiB
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 300MiB
Content: 260MiB
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 4GiB
Content: 260MiB
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 63x128MiB
Content: 500MiB
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 8GiB
Content: 300MiB
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 16GiB
Content: 1000MiB
Size: PASS
e2fsck: PASS
----------------------------------------

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.

[Bug]: Support a partial last block group to avoid expanding the EXT4 filesystem size

4 participants