apple / apple/containerization
[Bug]: Support a partial last block group to avoid expanding the EXT4 filesystem size
- Dominant language
- Swift
- Stars
- 8.9k
- Forks
- 359
- Avg merge
- 2d 20h
- Merged PRs (30d)
- 13
Description
### I have done the following
- [x] I have searched the existing issues
- [x] If possible, I've reproduced the issue using the 'main' branch of this project
### Steps to reproduce
Create an EXT4 filesystem with 160 MiB:
```
container volume create -s 160M size-test
stat -f%z ~/Library/Application\ Support/com.apple.container/volumes/size-test/volume.img
```
### Current behavior
When creating an EXT4 filesystem, the requested size is expanded to the nearest block group boundary. A filesystem whose requested size falls between two block group boundaries ends up larger than requested - 256 MiB:
```
268435456
```
### Expected behavior
The fix is to support a partial last block group so the filesystem uses exactly the requested size - 160 MiB:
```
167772160
```
### Environment
```markdown
N/A
```
### Relevant log output
Test results across the size/content matrix, cross-checked with `e2fsck`:
```shell
Requested Size: 32KiB
Content: none
Size: FAIL
audit.imageSize == testCase.requested = false; audit.imageSize = 134217728; testCase.requested = 32768
e2fsck: PASS
----------------------------------------
Requested Size: 64MiB
Content: none
Size: FAIL
audit.imageSize == testCase.requested = false; audit.imageSize = 134217728; testCase.requested = 67108864
e2fsck: PASS
----------------------------------------
Requested Size: 128MiB
Content: none
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 128MiB+4KiB
Content: none
Size: FAIL
audit.imageSize == testCase.requested = false; audit.imageSize = 268435456; testCase.requested = 134221824
e2fsck: PASS
----------------------------------------
Requested Size: 130MiB+8KiB
Content: none
Size: FAIL
audit.imageSize == testCase.requested = false; audit.imageSize = 268435456; testCase.requested = 136323072
e2fsck: PASS
----------------------------------------
Requested Size: 160MiB
Content: none
Size: FAIL
audit.imageSize == testCase.requested = false; audit.imageSize = 268435456; testCase.requested = 167772160
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 == testCase.requested = false; audit.imageSize = 8589934592; testCase.requested = 8455720960
e2fsck: PASS
----------------------------------------
Requested Size: 8GiB
Content: none
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 16GiB
Content: none
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 160MiB
Content: 10MiB
Size: FAIL
audit.imageSize == testCase.requested = false; audit.imageSize = 268435456; testCase.requested = 167772160
e2fsck: PASS
----------------------------------------
Requested Size: 128MiB
Content: 50MiB
Size: PASS
e2fsck: PASS
----------------------------------------
Requested Size: 160MiB
Content: 120MiB
Size: FAIL
audit.imageSize == testCase.requested = false; audit.imageSize = 268435456; testCase.requested = 167772160
e2fsck: PASS
----------------------------------------
Requested Size: 160MiB
Content: 124MiB
Size: FAIL
audit.imageSize == testCase.requested = false; audit.imageSize = 268435456; testCase.requested = 167772160
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: FAIL
audit.imageSize == testCase.requested = false; audit.imageSize = 402653184; testCase.requested = 314572800
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
----------------------------------------
```
### Code of Conduct
- [x] I agree to follow this project's Code of Conduct
Related to https://github.com/apple/containerization/pull/640.
Contributor guide
Assessment
This issue has not been assessed yet.