Skip to content

fix: memory over allocation due to last partial block group - #832

Open
siddh34 wants to merge 1 commit into
apple:mainfrom
siddh34:fix/memoryOverAllocation
Open

fix: memory over allocation due to last partial block group#832
siddh34 wants to merge 1 commit into
apple:mainfrom
siddh34:fix/memoryOverAllocation

Conversation

@siddh34

@siddh34siddh34 commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Description

This resolves issue #647

This is fix for memory over allocation due to last partial block

I have explicitly laid out metadata for extra/last groups

Modifications:

Packed-region math is computation starts at line 718

function to calculate blocks in last group at line 58

while loop here didn't made any sense so replaced it with if check line 914

@dkovbadkovba 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: 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: PASS
e2fsck: PASS
----------------------------------------
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: FAIL
allocatedMiB <= ceilingMiB = false; allocatedMiB = 65; ceilingMiB = 32
e2fsck: PASS
----------------------------------------
Requested Size: 63x128MiB
Content: none
Size: FAIL
allocatedMiB <= ceilingMiB = false; allocatedMiB = 127; ceilingMiB = 32
e2fsck: PASS
----------------------------------------
Requested Size: 63x128MiB+4KiB
Content: none
Size: FAIL
allocatedMiB <= ceilingMiB = false; allocatedMiB = 129; ceilingMiB = 32
e2fsck: FAIL rc=4
Block bitmap differences: +(32768--32930)
Fix? no
/imgs/63x128MiB+4KiB.img: ********** WARNING: Filesystem still has errors **********
/imgs/63x128MiB+4KiB.img: 11/524288 files (0.0% non-contiguous), 32737/2064385 blocks
----------------------------------------
Requested Size: 8GiB
Content: none
Size: FAIL
allocatedMiB <= ceilingMiB = false; allocatedMiB = 129; ceilingMiB = 32
e2fsck: FAIL rc=4
Block bitmap differences: +(32768--32930)
Fix? no
/imgs/8GiB.img: ********** WARNING: Filesystem still has errors **********
/imgs/8GiB.img: 11/524288 files (0.0% non-contiguous), 32737/2097152 blocks
----------------------------------------
Requested Size: 16GiB
Content: none
Size: FAIL
allocatedMiB <= ceilingMiB = false; allocatedMiB = 258; ceilingMiB = 32
e2fsck: FAIL rc=4
Block bitmap differences: +(32768--65826)
Fix? no
/imgs/16GiB.img: ********** WARNING: Filesystem still has errors **********
/imgs/16GiB.img: 11/1048576 files (0.0% non-contiguous), 32737/4194304 blocks
----------------------------------------
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: FAIL rc=4
Block bitmap differences: +(32768--32806)
Fix? no
/imgs/160MiB_124MiB-content.img: ********** WARNING: Filesystem still has errors **********
/imgs/160MiB_124MiB-content.img: 135/16384 files (0.0% non-contiguous), 32737/40960 blocks
----------------------------------------
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: FAIL rc=4
Block bitmap differences: +(131072--160417)
Fix? no
/imgs/63x128MiB_500MiB-content.img: ********** WARNING: Filesystem still has errors **********
/imgs/63x128MiB_500MiB-content.img: 511/516096 files (0.0% non-contiguous), 131041/2064384 blocks
----------------------------------------
Requested Size: 8GiB
Content: 300MiB
Size: PASS
e2fsck: FAIL rc=4
Block bitmap differences: +(98304--109730)
Fix? no
/imgs/8GiB_300MiB-content.img: ********** WARNING: Filesystem still has errors **********
/imgs/8GiB_300MiB-content.img: 311/524288 files (0.0% non-contiguous), 98273/2097152 blocks
----------------------------------------
Requested Size: 16GiB
Content: 1000MiB
Size: PASS
e2fsck: FAIL rc=4
Block bitmap differences: +(262144--321828)
Fix? no
/imgs/16GiB_1000MiB-content.img: ********** WARNING: Filesystem still has errors **********
/imgs/16GiB_1000MiB-content.img: 1011/1048576 files (0.0% non-contiguous), 262113/4194304 blocks
----------------------------------------

@siddh34

siddh34 commented Aug 7, 2026

Copy link
Copy Markdown
ContributorAuthor

@dkovba thanks for the tests I will update my pr in few days and will include these failed tests in it too!

@siddh34
siddh34force-pushed the fix/memoryOverAllocation branch from 98555ce to 16a7a7bCompareAugust 11, 2026 03:07
@siddh34
siddh34 requested a review from dkovbaAugust 11, 2026 03:36
@siddh34

siddh34 commented Aug 11, 2026

Copy link
Copy Markdown
ContributorAuthor

Updates after issues discovered in new test cases as given by @dkovba

  1. Reduced the allocated size by

defining minimum inodes per group at line 41

This tries multiple candidate values for inodesPerGroup line 1093 it basically means smaller inode tables less metadata overhead

  1. Bitmap fixes as follows

Now ext4 block bitmaps are per-group. Changes can be found at line 879

basically marking the packed metadata blocks that physically live inside a group as allocated in that group’s block bitmap

also tested with e2fsck

CASE: 32KiB_none
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-92C353EF-EC99-40C4-8630-94E6E7CA3F46/32KiB_none.img
requested: 32768 bytes
content: 0 bytes
allocatedMiB: 0
e2fsck rc: 0
CASE: 64MiB_none
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-92C353EF-EC99-40C4-8630-94E6E7CA3F46/64MiB_none.img
requested: 67108864 bytes
content: 0 bytes
allocatedMiB: 0
e2fsck rc: 0
CASE: 128MiB_none
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-92C353EF-EC99-40C4-8630-94E6E7CA3F46/128MiB_none.img
requested: 134217728 bytes
content: 0 bytes
allocatedMiB: 0
e2fsck rc: 0
CASE: 128MiB+4KiB_none
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-92C353EF-EC99-40C4-8630-94E6E7CA3F46/128MiB+4KiB_none.img
requested: 134221824 bytes
content: 0 bytes
allocatedMiB: 0
e2fsck rc: 0
CASE: 130MiB+8KiB_none
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-92C353EF-EC99-40C4-8630-94E6E7CA3F46/130MiB+8KiB_none.img
requested: 136323072 bytes
content: 0 bytes
allocatedMiB: 0
e2fsck rc: 0
CASE: 160MiB_none
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-92C353EF-EC99-40C4-8630-94E6E7CA3F46/160MiB_none.img
requested: 167772160 bytes
content: 0 bytes
allocatedMiB: 0
e2fsck rc: 0
CASE: 256MiB_none
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-92C353EF-EC99-40C4-8630-94E6E7CA3F46/256MiB_none.img
requested: 268435456 bytes
content: 0 bytes
allocatedMiB: 0
e2fsck rc: 0
CASE: 1GiB_none
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-92C353EF-EC99-40C4-8630-94E6E7CA3F46/1GiB_none.img
requested: 1073741824 bytes
content: 0 bytes
allocatedMiB: 1
e2fsck rc: 0
CASE: 4GiB_none
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-92C353EF-EC99-40C4-8630-94E6E7CA3F46/4GiB_none.img
requested: 4294967296 bytes
content: 0 bytes
allocatedMiB: 7
e2fsck rc: 0
CASE: 63x128MiB_none
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-92C353EF-EC99-40C4-8630-94E6E7CA3F46/63x128MiB_none.img
requested: 8455716864 bytes
content: 0 bytes
allocatedMiB: 14
e2fsck rc: 0
CASE: 63x128MiB+4KiB_none
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-92C353EF-EC99-40C4-8630-94E6E7CA3F46/63x128MiB+4KiB_none.img
requested: 8455720960 bytes
content: 0 bytes
allocatedMiB: 14
e2fsck rc: 0
CASE: 8GiB_none
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-92C353EF-EC99-40C4-8630-94E6E7CA3F46/8GiB_none.img
requested: 8589934592 bytes
content: 0 bytes
allocatedMiB: 14
e2fsck rc: 0
CASE: 16GiB_none
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-92C353EF-EC99-40C4-8630-94E6E7CA3F46/16GiB_none.img
requested: 17179869184 bytes
content: 0 bytes
allocatedMiB: 29
e2fsck rc: 0
CASE: 160MiB_10MiB
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-92C353EF-EC99-40C4-8630-94E6E7CA3F46/160MiB_10MiB.img
requested: 167772160 bytes
content: 10485760 bytes
allocatedMiB: 10
e2fsck rc: 0
CASE: 128MiB_50MiB
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-92C353EF-EC99-40C4-8630-94E6E7CA3F46/128MiB_50MiB.img
requested: 134217728 bytes
content: 52428800 bytes
allocatedMiB: 50
e2fsck rc: 0
CASE: 160MiB_120MiB
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-92C353EF-EC99-40C4-8630-94E6E7CA3F46/160MiB_120MiB.img
requested: 167772160 bytes
content: 125829120 bytes
allocatedMiB: 120
e2fsck rc: 0
CASE: 160MiB_124MiB
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-92C353EF-EC99-40C4-8630-94E6E7CA3F46/160MiB_124MiB.img
requested: 167772160 bytes
content: 130023424 bytes
allocatedMiB: 124
e2fsck rc: 0
CASE: 160MiB_126MiB
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-92C353EF-EC99-40C4-8630-94E6E7CA3F46/160MiB_126MiB.img
requested: 167772160 bytes
content: 132120576 bytes
allocatedMiB: 126
e2fsck rc: 0
CASE: 256MiB_130MiB
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-92C353EF-EC99-40C4-8630-94E6E7CA3F46/256MiB_130MiB.img
requested: 268435456 bytes
content: 136314880 bytes
allocatedMiB: 130
e2fsck rc: 0
CASE: 1GiB_200MiB
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-92C353EF-EC99-40C4-8630-94E6E7CA3F46/1GiB_200MiB.img
requested: 1073741824 bytes
content: 209715200 bytes
allocatedMiB: 201
e2fsck rc: 0
CASE: 300MiB_260MiB
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-92C353EF-EC99-40C4-8630-94E6E7CA3F46/300MiB_260MiB.img
requested: 314572800 bytes
content: 272629760 bytes
allocatedMiB: 260
e2fsck rc: 0
CASE: 4GiB_260MiB
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-92C353EF-EC99-40C4-8630-94E6E7CA3F46/4GiB_260MiB.img
requested: 4294967296 bytes
content: 272629760 bytes
allocatedMiB: 267
e2fsck rc: 0
CASE: 63x128MiB_500MiB
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-92C353EF-EC99-40C4-8630-94E6E7CA3F46/63x128MiB_500MiB.img
requested: 8455716864 bytes
content: 524288000 bytes
allocatedMiB: 514
e2fsck rc: 0
CASE: 8GiB_300MiB
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-92C353EF-EC99-40C4-8630-94E6E7CA3F46/8GiB_300MiB.img
requested: 8589934592 bytes
content: 314572800 bytes
allocatedMiB: 314
e2fsck rc: 0
CASE: 16GiB_1000MiB
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-92C353EF-EC99-40C4-8630-94E6E7CA3F46/16GiB_1000MiB.img
requested: 17179869184 bytes
content: 1048576000 bytes
allocatedMiB: 1029
e2fsck rc: 0
========== E2FSCK SUMMARY ==========
All 25 cases passed.

@dkovba please check according to your convience, thanks!

Open to making any changes needed or I missed for this current pull request

@dkovbadkovba 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 updating the PR!

Comment threadSources/ContainerizationEXT4/EXT4+Formatter.swift Outdated
Comment threadTests/ContainerizationEXT4Tests/TestEXT4Format.swift
Comment threadTests/ContainerizationEXT4Tests/TestEXT4Format.swift
Comment threadTests/ContainerizationEXT4Tests/TestEXT4Format.swift
Comment threadTests/ContainerizationEXT4Tests/TestEXT4Format.swift
Comment threadSources/ContainerizationEXT4/EXT4+Formatter.swift Outdated

@dkovbadkovba 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.

With the suggested implementation of the partial block support, we use significantly more physical space than on main and than mke2fs does.

With minimumInodesPerGroup: UInt32 = 896:

Requested Size: 16GiB
Content: none
Size: PASS
e2fsck: PASS
Logical Size vs mke2fs: PASS
Physical Size vs mke2fs: FAIL
physical <= mke2fs = false; physical = 30,457,856; mke2fs = 4,816,896

With the original block size derivation:

Requested Size: 16GiB
Content: none
Size: PASS
e2fsck: PASS
Logical Size vs mke2fs: PASS
Physical Size vs mke2fs: FAIL
physical <= mke2fs = false; physical = 269,647,872; mke2fs = 4,816,896

Comment threadSources/ContainerizationEXT4/EXT4+Formatter.swift Outdated
@siddh34
siddh34force-pushed the fix/memoryOverAllocation branch from 16a7a7b to b01028bCompareAugust 15, 2026 11:36
@siddh34
siddh34 requested a review from dkovbaAugust 15, 2026 11:41
@siddh34
siddh34force-pushed the fix/memoryOverAllocation branch from b01028b to 0594735CompareAugust 15, 2026 11:42
@siddh34

siddh34 commented Aug 15, 2026

Copy link
Copy Markdown
ContributorAuthor

With the suggested implementation of the partial block support, we use significantly more physical space than on main and than mke2fs does.

With minimumInodesPerGroup: UInt32 = 896:

Requested Size: 16GiB
Content: none
Size: PASS
e2fsck: PASS
Logical Size vs mke2fs: PASS
Physical Size vs mke2fs: FAIL
physical <= mke2fs = false; physical = 30,457,856; mke2fs = 4,816,896

With the original block size derivation:

Requested Size: 16GiB
Content: none
Size: PASS
e2fsck: PASS
Logical Size vs mke2fs: PASS
Physical Size vs mke2fs: FAIL
physical <= mke2fs = false; physical = 269,647,872; mke2fs = 4,816,896

Tested with

letinc=Int(self.blockSize *self.inodeStrideKiB)/ Int(EXT4.InodeSize) // minimizes the number of blockGroups needed to its lowest value

where self.inodeStrideKiB = 512

Results

Requested Size: 128MiB
Content: none
Size: PASS
e2fsck: PASS
Our logical size: 128MiB, mke2fs logical size: 128MiB
Our physical size: 2072KiB, mke2fs physical size: 14011KiB
Logical Size vs mke2fs: PASS
Physical Size vs mke2fs: PASS
Requested Size: 1GiB
Content: none
Size: PASS
e2fsck: PASS
Our logical size: 1GiB, mke2fs logical size: 1GiB
Our physical size: 16464KiB, mke2fs physical size: 52076KiB
Logical Size vs mke2fs: PASS
Physical Size vs mke2fs: PASS
Requested Size: 4GiB
Content: none
Size: PASS
e2fsck: PASS
Our logical size: 4GiB, mke2fs logical size: 4GiB
Our physical size: 65808KiB, mke2fs physical size: 148792KiB
Logical Size vs mke2fs: PASS
Physical Size vs mke2fs: PASS
Requested Size: 8GiB
Content: none
Size: PASS
e2fsck: PASS
Our logical size: 8GiB, mke2fs logical size: 8GiB
Our physical size: 131600KiB, mke2fs physical size: 234052KiB
Logical Size vs mke2fs: PASS
Physical Size vs mke2fs: PASS
Requested Size: 16GiB
Content: none
Size: PASS
e2fsck: PASS
Our logical size: 16GiB, mke2fs logical size: 16GiB
Our physical size: 263184KiB, mke2fs physical size: 439460KiB
Logical Size vs mke2fs: PASS
Physical Size vs mke2fs: PASS

Here is my script for tests

import ContainerizationArchive
import Foundation
import SystemPackage
import Testing
@testableimport ContainerizationEXT4
structE2FsckImageCase:Sendable{letname:StringletimagePath:FilePathletrequestedSize:UInt64letcontentSize:UInt64init(
name:String,
imagePath:FilePath,
requestedSize:UInt64,
contentSize:UInt64=0){self.name = name
self.imagePath = imagePath
self.requestedSize = requestedSize
self.contentSize = contentSize
}}structE2FsckResult:Sendable{letexitCode:Int32letstdout:Stringletstderr:Stringvarpassed:Bool{
exitCode ==0}}structEXT4E2FsckHarness{lete2fsckPath:Stringletmke2fsPath:Stringinit(
e2fsckPath:String="/opt/homebrew/Cellar/e2fsprogs/1.47.4/sbin/e2fsck",
mke2fsPath:String="/opt/homebrew/Cellar/e2fsprogs/1.47.4/sbin/mke2fs"){self.e2fsckPath = e2fsckPath
self.mke2fsPath = mke2fsPath
}func createReferenceImage(requestedSize:UInt64, at imagePath:FilePath)throws{ifFileManager.default.fileExists(atPath: imagePath.string){tryFileManager.default.removeItem(at: imagePath.url)}FileManager.default.createFile(atPath: imagePath.string, contents:nil)lethandle=tryFileHandle(forWritingTo: imagePath.url)try handle.truncate(atOffset: requestedSize)try handle.close()letprocess=Process()
process.executableURL =URL(fileURLWithPath: mke2fsPath)
process.arguments =["-F","-q","-t","ext4", imagePath.string]letstderrPipe=Pipe()
process.standardError = stderrPipe
process.standardOutput =Pipe()try process.run()
process.waitUntilExit()guard process.terminationStatus ==0else{leterr=String(decoding: stderrPipe.fileHandleForReading.readDataToEndOfFile(), as:UTF8.self)structMkE2FsError:Swift.Error,CustomStringConvertible{letdescription:String}throwMkE2FsError(description:"mke2fs failed: \(err)")}}func createImage(for testCase:E2FsckImageCase)throws{letformatter=tryEXT4.Formatter(
testCase.imagePath,
minDiskSize: testCase.requestedSize
)if testCase.contentSize >0{letchunkSize=min(testCase.contentSize,1.mib())letchunk=Data(repeating:0x41, count:Int(chunkSize))letstream=RepeatingDataStream(chunk: chunk, totalBytes: testCase.contentSize)try formatter.create(
path:FilePath("/content.bin"),
mode:EXT4.Inode.Mode(.S_IFREG,0o644),
buf: stream
)}try formatter.close()}func runE2Fsck(on imagePath:FilePath)throws->E2FsckResult{letprocess=Process()
process.executableURL =URL(fileURLWithPath: e2fsckPath)
process.arguments =["-fn", imagePath.string]letstdoutPipe=Pipe()letstderrPipe=Pipe()
process.standardOutput = stdoutPipe
process.standardError = stderrPipe
try process.run()
process.waitUntilExit()letstdoutData= stdoutPipe.fileHandleForReading.readDataToEndOfFile()letstderrData= stderrPipe.fileHandleForReading.readDataToEndOfFile()returnE2FsckResult(
exitCode: process.terminationStatus,
stdout:String(decoding: stdoutData, as:UTF8.self),
stderr:String(decoding: stderrData, as:UTF8.self))}func deleteImage(at imagePath:FilePath)throws{ifFileManager.default.fileExists(atPath: imagePath.string){tryFileManager.default.removeItem(at: imagePath.url)}}func imageSize(at imagePath:FilePath)throws->UInt64{lethandle=tryFileHandle(forReadingFrom: imagePath.url)returntry handle.seekToEnd()}func allocatedMiB(at imagePath:FilePath)throws->UInt64{letext4=tryEXT4.EXT4Reader(blockDevice: imagePath)letsb= ext4.superBlock
letblocksCount=UInt64(sb.blocksCountLow) | (UInt64(sb.blocksCountHigh) << 32)letfreeBlocks=UInt64(sb.freeBlocksCountLow) | (UInt64(sb.freeBlocksCountHigh) << 32)letusedBlocks= blocksCount - freeBlocks
letusedBytes= usedBlocks * UInt64(sb.blockSize)return usedBytes /1024/1024}
// Physical (used) and logical (file) size for any existing ext4 image, ours or a reference.
func footprint(at imagePath:FilePath)throws->(logicalBytes:UInt64, physicalBytes:UInt64){letlogicalBytes=tryimageSize(at: imagePath)letext4=tryEXT4.EXT4Reader(blockDevice: imagePath)letsb= ext4.superBlock
letblocksCount=UInt64(sb.blocksCountLow) | (UInt64(sb.blocksCountHigh) << 32)letfreeBlocks=UInt64(sb.freeBlocksCountLow) | (UInt64(sb.freeBlocksCountHigh) << 32)letphysicalBytes=(blocksCount - freeBlocks)* UInt64(sb.blockSize)return(logicalBytes, physicalBytes)}}finalclassRepeatingDataStream:ReadableStream{privateletchunk:DataprivatelettotalBytes:UInt64privatevarwrittenBytes:UInt64=0privatevarchunkOffset:Int=0init(chunk:Data, totalBytes:UInt64){self.chunk = chunk
self.totalBytes = totalBytes
}func read(_ buffer:UnsafeMutablePointer<UInt8>, maxLength len:Int)->Int{guard writtenBytes < totalBytes else{return0}letremaining=Int(min(UInt64(len), totalBytes - writtenBytes))letbytes= chunk.withUnsafeBytes{ chunkBytes inguardlet base = chunkBytes.baseAddress?.assumingMemoryBound(to:UInt8.self)else{return0}varcopied=0while copied < remaining {letavailable= chunk.count - chunkOffset
lettoCopy=min(remaining - copied, available)
buffer.advanced(by: copied).update(from: base.advanced(by: chunkOffset), count: toCopy)
copied += toCopy
chunkOffset =(chunkOffset + toCopy)% chunk.count
}return copied
}
writtenBytes +=UInt64(bytes)return bytes
}}privatefunc formatBytes(_ bytes:UInt64)->String{letunits:[(UInt64,String)]=[(1.gib(),"GiB"),(1.mib(),"MiB"),(1.kib(),"KiB")]for(size, label)in units where bytes >= size && bytes % size ==0{return"\(bytes / size)\(label)"}return"\(bytes)B"}privatefunc formatCount(_ n:UInt64)->String{letformatter=NumberFormatter()
formatter.numberStyle =.decimal
return formatter.string(from:NSNumber(value: n))??"\(n)"}@Testfunc e2FsckMatrixComparesAgainstMke2fs()throws{letharness=EXT4E2FsckHarness()letcases:[(name:String, requested:UInt64, content:UInt64)]=[
// ("32KiB_none", 32.kib(), 0),
// ("64MiB_none", 64.mib(), 0),
("128MiB_none",128.mib(),0),("1GiB_none",1.gib(),0),("4GiB_none",4.gib(),0),("8GiB_none",8.gib(),0),("16GiB_none",16.gib(),0),]letroot=FileManager.default.temporaryDirectory
.appendingPathComponent("ext4-mke2fs-compare-\(UUID().uuidString)", isDirectory:true)tryFileManager.default.createDirectory(at: root, withIntermediateDirectories:true)defer{try?FileManager.default.removeItem(at: root)}fortestCasein cases {letourImage=FilePath(root.appendingPathComponent("\(testCase.name)-ours.img", isDirectory:false))letrefImage=FilePath(root.appendingPathComponent("\(testCase.name)-ref.img", isDirectory:false))try harness.createImage(
for:E2FsckImageCase(name: testCase.name, imagePath: ourImage, requestedSize: testCase.requested, contentSize: testCase.content))try harness.createReferenceImage(requestedSize: testCase.requested, at: refImage)letfsckResult=try harness.runE2Fsck(on: ourImage)letours=try harness.footprint(at: ourImage)letreference=try harness.footprint(at: refImage)letsizePass= ours.logicalBytes == testCase.requested
letfsckPass= fsckResult.passed
letlogicalPass= ours.logicalBytes == reference.logicalBytes
letphysicalPass= ours.physicalBytes <= reference.physicalBytes
print("Requested Size: \(formatBytes(testCase.requested))")print("Content: \(testCase.content >0?formatBytes(testCase.content):"none")")print("Size: \(sizePass ?"PASS":"FAIL")")print("e2fsck: \(fsckPass ?"PASS":"FAIL")")print("Our logical size: \(formatBytes(ours.logicalBytes)), mke2fs logical size: \(formatBytes(reference.logicalBytes))")print("Our physical size: \(formatBytes(ours.physicalBytes)), mke2fs physical size: \(formatBytes(reference.physicalBytes))")print("Logical Size vs mke2fs: \(logicalPass ?"PASS":"FAIL")")print("Physical Size vs mke2fs: \(physicalPass ?"PASS":"FAIL")")if !physicalPass {print("physical <= mke2fs = false; physical = \(formatCount(ours.physicalBytes)); mke2fs = \(formatCount(reference.physicalBytes))")}
#expect(sizePass)
#expect(fsckPass)
#expect(physicalPass,"physical <= mke2fs = false; physical = \(ours.physicalBytes); mke2fs = \(reference.physicalBytes)")}}

@dkovba please check when it is convenient for you

also please reply to comment

@siddh34
siddh34force-pushed the fix/memoryOverAllocation branch 2 times, most recently from c167cb3 to 3d888eeCompareAugust 15, 2026 17:23
@dkovba

Copy link
Copy Markdown
Contributor

It seems this code gives allocated size, ignoring sparseness:

 let physicalBytes = (blocksCount - freeBlocks) * UInt64(sb.blockSize)

Consider something like this:

func physicalBytes(at imagePath: FilePath) throws -> UInt64 {
let handle = try FileHandle(forReadingFrom: imagePath.url)
defer { try? handle.close() }
guard fsync(handle.fileDescriptor) == 0 else {
throw POSIXError(POSIXErrorCode(rawValue: errno) ?? .EIO)
}
var st = stat()
guard stat(imagePath.string, &st) == 0 else {
throw POSIXError(POSIXErrorCode(rawValue: errno) ?? .EIO)
}
return UInt64(st.st_blocks) * 512
}

Test results for mke2fs (with no content only):

----------------------------------------
Requested size: 4GiB
Content: none
Logical size: PASS
Physical size: PASS
e2fsck: PASS
Logical size vs mke2fs (no journal): PASS
Physical size vs mke2fs (no journal): FAIL
physical <= mke2fs = false; physical = 67,534,848; mke2fs = 2,523,136
Physical size vs mke2fs (journalled): PASS
----------------------------------------
Requested size: 63x128MiB
Content: none
Logical size: PASS
Physical size: PASS
e2fsck: PASS
Logical size vs mke2fs (no journal): PASS
Physical size vs mke2fs (no journal): FAIL
physical <= mke2fs = false; physical = 132,808,704; mke2fs = 4,636,672
Physical size vs mke2fs (journalled): FAIL
physical <= mke2fs = false; physical = 137,920,512; mke2fs = 73,809,920
----------------------------------------
Requested size: 63x128MiB+4KiB
Content: none
Logical size: PASS
Physical size: PASS
e2fsck: PASS
Logical size vs mke2fs (no journal): PASS
Physical size vs mke2fs (no journal): FAIL
physical <= mke2fs = false; physical = 134,893,568; mke2fs = 4,640,768
Physical size vs mke2fs (journalled): FAIL
physical <= mke2fs = false; physical = 137,895,936; mke2fs = 73,814,016
----------------------------------------
Requested size: 8GiB
Content: none
Logical size: PASS
Physical size: PASS
e2fsck: PASS
Logical size vs mke2fs (no journal): PASS
Physical size vs mke2fs (no journal): FAIL
physical <= mke2fs = false; physical = 134,905,856; mke2fs = 4,702,208
Physical size vs mke2fs (journalled): FAIL
physical <= mke2fs = false; physical = 140,050,432; mke2fs = 71,827,456
----------------------------------------
Requested size: 16GiB
Content: none
Logical size: PASS
Physical size: PASS
e2fsck: PASS
Logical size vs mke2fs (no journal): PASS
Physical size vs mke2fs (no journal): FAIL
physical <= mke2fs = false; physical = 269,647,872; mke2fs = 4,816,896
Physical size vs mke2fs (journalled): FAIL
physical <= mke2fs = false; physical = 141,623,296; mke2fs = 138,985,472
----------------------------------------

@siddh34

Copy link
Copy Markdown
ContributorAuthor

@dkovba I will make some changes in few days. Thanks for pointing my tests in correct direction

@siddh34
siddh34force-pushed the fix/memoryOverAllocation branch from 3d888ee to e57324dCompareAugust 22, 2026 04:06
@siddh34

Copy link
Copy Markdown
ContributorAuthor

@dkovba I was able to reduce physical size across file allocation

I want to ask you about the journal size you are use for testing containerization vs mke2fs (journalled)?

letcases:[(name:String, requested:UInt64, content:UInt64, journalSize:UInt64?)]=[("128MiB_nojournal",128.mib(),0,nil),("1GiB_nojournal",1.gib(),0,nil),("4GiB_nojournal",4.gib(),0,nil),("8GiB_nojournal",8.gib(),0,nil),("16GiB_nojournal",16.gib(),0,nil),("128MiB_journal",128.mib(),0,4.mib()),("63x128MiB_journal",63*128.mib(),0,32.mib()),("63x128MiB+4KiB_journal",63*128.mib()+4.kib(),0,32.mib()),("1GiB_journal",1.gib(),0,32.mib()),("4GiB_journal",4.gib(),0,64.mib()),("8GiB_journal",8.gib(),0,128.mib()),("16GiB_journal",16.gib(),0,256.mib()),]

This are the test cases I am testing them with.

This test cases are passing, result is pasted as below

Requested Size: 128MiB
Content: none
Journal: disabled
Size: PASS
e2fsck: PASS
Our logical size: 128MiB, mke2fs logical size: 128MiB
Our physical size: 2224KiB, mke2fs physical size: 73808KiB
Logical Size vs mke2fs: PASS
Physical Size vs mke2fs: PASS
Requested Size: 1GiB
Content: none
Journal: disabled
Size: PASS
e2fsck: PASS
Our logical size: 1GiB, mke2fs logical size: 1GiB
Our physical size: 2272KiB, mke2fs physical size: 50144KiB
Logical Size vs mke2fs: PASS
Physical Size vs mke2fs: PASS
Requested Size: 4GiB
Content: none
Journal: disabled
Size: PASS
e2fsck: PASS
Our logical size: 4GiB, mke2fs logical size: 4GiB
Our physical size: 2464KiB, mke2fs physical size: 69024KiB
Logical Size vs mke2fs: PASS
Physical Size vs mke2fs: PASS
Requested Size: 8GiB
Content: none
Journal: disabled
Size: PASS
e2fsck: PASS
Our logical size: 8GiB, mke2fs logical size: 8GiB
Our physical size: 2720KiB, mke2fs physical size: 70144KiB
Logical Size vs mke2fs: PASS
Physical Size vs mke2fs: PASS
Requested Size: 16GiB
Content: none
Journal: disabled
Size: PASS
e2fsck: PASS
Our logical size: 16GiB, mke2fs logical size: 16GiB
Our physical size: 3232KiB, mke2fs physical size: 135728KiB
Logical Size vs mke2fs: PASS
Physical Size vs mke2fs: PASS
Requested Size: 128MiB
Content: none
Journal: 4MiB
Size: PASS
e2fsck: PASS
Our logical size: 132MiB, mke2fs logical size: 132MiB
Our physical size: 10416KiB, mke2fs physical size: 77840KiB
Logical Size vs mke2fs: PASS
Physical Size vs mke2fs: PASS
Requested Size: 8064MiB
Content: none
Journal: 32MiB
Size: PASS
e2fsck: PASS
Our logical size: 8096MiB, mke2fs logical size: 8096MiB
Our physical size: 2736KiB, mke2fs physical size: 39344KiB
Logical Size vs mke2fs: PASS
Physical Size vs mke2fs: PASS
Requested Size: 8257540KiB
Content: none
Journal: 32MiB
Size: PASS
e2fsck: PASS
Our logical size: 8290308KiB, mke2fs logical size: 8290308KiB
Our physical size: 2736KiB, mke2fs physical size: 39348KiB
Logical Size vs mke2fs: PASS
Physical Size vs mke2fs: PASS
Requested Size: 1GiB
Content: none
Journal: 32MiB
Size: PASS
e2fsck: PASS
Our logical size: 1056MiB, mke2fs logical size: 1056MiB
Our physical size: 2304KiB, mke2fs physical size: 33808KiB
Logical Size vs mke2fs: PASS
Physical Size vs mke2fs: PASS
Requested Size: 4GiB
Content: none
Journal: 64MiB
Size: PASS
e2fsck: PASS
Our logical size: 4160MiB, mke2fs logical size: 4160MiB
Our physical size: 2496KiB, mke2fs physical size: 69072KiB
Logical Size vs mke2fs: PASS
Physical Size vs mke2fs: PASS
Requested Size: 8GiB
Content: none
Journal: 128MiB
Size: PASS
e2fsck: PASS
Our logical size: 8320MiB, mke2fs logical size: 8320MiB
Our physical size: 4800KiB, mke2fs physical size: 135632KiB
Logical Size vs mke2fs: PASS
Physical Size vs mke2fs: PASS
Requested Size: 16GiB
Content: none
Journal: 256MiB
Size: PASS
e2fsck: PASS
Our logical size: 16640MiB, mke2fs logical size: 16640MiB
Our physical size: 7360KiB, mke2fs physical size: 266848KiB
Logical Size vs mke2fs: PASS
Physical Size vs mke2fs: PASS

Also I faced a issue with highlighted line, so I am commenting this

superblock.journalUUID = filesystemUUID

as e2fsck was searching for external journal when we aren't writing external journal

the error is as follow

Requested Size: 128MiB
Content: none
Journal: 4MiB
Size: PASS
e2fsck: FAIL
Our logical size: 132MiB, mke2fs logical size: 132MiB
Our physical size: 10416KiB, mke2fs physical size: 77840KiB
Logical Size vs mke2fs: PASS
Physical Size vs mke2fs: PASS
===== e2fsck failure: 128MiB_journal =====
Can't find external journal
/var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-mke2fs-compare-0D2CD8CD-A8E6-4A30-86D5-0D4D6D1A72DF/128MiB_journal-ours.img: ********** WARNING: Filesystem still has errors **********
e2fsck 1.47.4 (6-Mar-2025)
✘ Test e2FsckMatrixComparesAgainstMke2fs() recorded an issue at TestEXT4Format+E2Fsck.swift:584:9: Expectation failed: fsckPass
✘ Test e2FsckMatrixComparesAgainstMke2fs() failed after 0.054 seconds with 1 issue.
✘ Test run with 1 test in 0 suites failed after 0.054 seconds with 1 issue.

Comment threadSources/ContainerizationEXT4/EXT4+Formatter.swift Outdated
Comment threadTests/ContainerizationEXT4Tests/TestEXT4Format.swift
Comment threadSources/ContainerizationEXT4/EXT4+Journal.swift Outdated
Comment threadSources/ContainerizationEXT4/EXT4+Journal.swift Outdated
@siddh34
siddh34force-pushed the fix/memoryOverAllocation branch 2 times, most recently from 1412537 to 02283ddCompareAugust 27, 2026 19:33
@siddh34

siddh34 commented Aug 27, 2026

Copy link
Copy Markdown
ContributorAuthor

@dkovba I will keep the branch in sync with main until it get merged. Also open to making more changes for this PR if something I missed

@siddh34
siddh34force-pushed the fix/memoryOverAllocation branch from 02283dd to a1b6496CompareAugust 27, 2026 19:52
Comment threadTests/ContainerizationEXT4Tests/TestEXT4Format.swift Outdated
Comment threadSources/ContainerizationEXT4/EXT4+Formatter.swift Outdated
Comment threadTests/ContainerizationEXT4Tests/TestEXT4Format.swift
Comment threadSources/ContainerizationEXT4/EXT4+Formatter.swift Outdated
@siddh34
siddh34force-pushed the fix/memoryOverAllocation branch 2 times, most recently from 499337d to af47d80CompareAugust 29, 2026 01:36

@dkovbadkovba 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.

Another test case that fails to pass the e2fsck check:

Requested Size: 128MiB+4KiB
Content: 124MiB
Logical size: PASS
Physical size: PASS
e2fsck: FAIL rc=8
ext2fs_check_desc: Corrupt group descriptor: bad block for inode table
/opt/homebrew/opt/e2fsprogs/sbin/e2fsck: Group descriptors look bad... trying backup blocks...
Note: if several inode or block bitmap blocks or part
of the inode table require relocation, you may wish to try
running e2fsck with the '-b 8193' option first. The problem
may lie only with the primary block group descriptors, and
the backup block group descriptors may be OK.
Inode table for group 1 is not in group. (block 32295)
WARNING: SEVERE DATA LOSS POSSIBLE.
Relocate? no
Pass 1: Checking inodes, blocks, and sizes
Illegal block number passed to ext2fs_test_block_bitmap #32769 for in-use block map
...
Illegal block number passed to ext2fs_mark_block_bitmap #32806 for metadata block map
Error while scanning inodes (8192): Corrupt group descriptor: bad block for inode table
e2fsck: aborted

@siddh34

siddh34 commented Aug 29, 2026

Copy link
Copy Markdown
ContributorAuthor

@dkovba thanks for pointing it out I will update the pull request by the EOD

testing a few more possibilities like it

@dkovbadkovba 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.

Another similar failure, which seems to be caused by a different issue:

Requested size: 128MiB+4KiB
Content: 125MiB+218*4KiB
Logical size: FAIL
audit.imageSize = 134225920; audit.blocksCount * 4.kib() = 134221824
audit.imageSize = 134225920; expectedSize = 134221824
Physical size: PASS
e2fsck: FAIL rc=8
ext2fs_check_desc: Corrupt group descriptor: bad block for inode 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
the backup block group descriptors may be OK.
Inode bitmap for group 1 is not in group. (block 32769)
Relocate? no
Inode table for group 1 is not in group. (block 32770)
WARNING: SEVERE DATA LOSS POSSIBLE.
Relocate? no
Illegal block number passed to ext2fs_test_block_bitmap #32770 for in-use block map
...
Illegal block number passed to ext2fs_mark_block_bitmap #32779 for metadata block map

@siddh34
siddh34force-pushed the fix/memoryOverAllocation branch from af47d80 to 14f1728CompareAugust 29, 2026 08:17
@siddh34

Copy link
Copy Markdown
ContributorAuthor

@dkovba I have updated my local test suite for new changes also added new tests cases to the current tests. Please check according to your convenience

local tests logs

CASE: 128MiB_4KiB
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-48239871-9D72-4659-BF56-168EDE21F7A6/128MiB_4KiB.img
requested: 134221824 bytes
content: 4096 bytes
allocatedMiB: 2
e2fsck rc: 0
CASE: 128MiB_124MiB
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-48239871-9D72-4659-BF56-168EDE21F7A6/128MiB_124MiB.img
requested: 134221824 bytes
content: 130023424 bytes
allocatedMiB: 128
e2fsck rc: 0
CASE: 128MiB+4KiB_100MiB
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-48239871-9D72-4659-BF56-168EDE21F7A6/128MiB+4KiB_100MiB.img
requested: 134221824 bytes
content: 104857600 bytes
allocatedMiB: 102
e2fsck rc: 0
CASE: 128MiB+4KiB_120MiB
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-48239871-9D72-4659-BF56-168EDE21F7A6/128MiB+4KiB_120MiB.img
requested: 134221824 bytes
content: 125829120 bytes
allocatedMiB: 128
e2fsck rc: 0
CASE: 128MiB+4KiB_126MiB
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-48239871-9D72-4659-BF56-168EDE21F7A6/128MiB+4KiB_126MiB.img
requested: 134221824 bytes
content: 132120576 bytes
allocatedMiB: 130
e2fsck rc: 0
CASE: 128MiB+4KiB_127MiB
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-48239871-9D72-4659-BF56-168EDE21F7A6/128MiB+4KiB_127MiB.img
requested: 134221824 bytes
content: 133169152 bytes
allocatedMiB: 131
e2fsck rc: 0
CASE: 128MiB+8KiB_124MiB
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-48239871-9D72-4659-BF56-168EDE21F7A6/128MiB+8KiB_124MiB.img
requested: 134225920 bytes
content: 130023424 bytes
allocatedMiB: 128
e2fsck rc: 0
CASE: 128MiB+12KiB_124MiB
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-48239871-9D72-4659-BF56-168EDE21F7A6/128MiB+12KiB_124MiB.img
requested: 134230016 bytes
content: 130023424 bytes
allocatedMiB: 128
e2fsck rc: 0
CASE: 128MiB+24KiB_124MiB
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-48239871-9D72-4659-BF56-168EDE21F7A6/128MiB+24KiB_124MiB.img
requested: 134242304 bytes
content: 130023424 bytes
allocatedMiB: 128
e2fsck rc: 0
CASE: 256MiB+4KiB_252MiB
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-48239871-9D72-4659-BF56-168EDE21F7A6/256MiB+4KiB_252MiB.img
requested: 268439552 bytes
content: 264241152 bytes
allocatedMiB: 258
e2fsck rc: 0
CASE: 384MiB+4KiB_380MiB
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-48239871-9D72-4659-BF56-168EDE21F7A6/384MiB+4KiB_380MiB.img
requested: 402657280 bytes
content: 398458880 bytes
allocatedMiB: 388
e2fsck rc: 0
CASE: 128MiB+4KiB_125MiB+218blk
image: /var/folders/y4/rkj6lthx2vg9ls8cbyyy8nb00000gn/T/ext4-e2fsck-matrix-48239871-9D72-4659-BF56-168EDE21F7A6/128MiB+4KiB_125MiB+218blk.img
requested: 134221824 bytes
content: 131964928 bytes
allocatedMiB: 128
e2fsck rc: 0
========== E2FSCK SUMMARY ==========
All 12 cases passed.

@siddh34
siddh34 requested a review from dkovbaAugust 29, 2026 08:27

@dkovbadkovba 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.

This test case crashes in two places:

Requested size: 128MiB
Content: none
CRASH: Sources/ContainerizationEXT4/EXT4+Journal.swift:160
Requested size: 128MiB
Content: none
CRASH: Sources/ContainerizationEXT4/EXT4+Journal.swift:56

@dkovbadkovba 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.

And this one fails the logical size check:

Requested size: 128MiB+60KiB
Content: 125MiB+177*4KiB
Logical size: FAIL
audit.imageSize == audit.blocksCount * 4.kib() = false; audit.imageSize = 134279168; audit.blocksCount * 4.kib() = 134217728
Physical size: PASS
e2fsck: PASS
e2fsck (journalled): PASS

Sign up for freeto 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.

2 participants

@siddh34@dkovba