Skip to content

Adds journal modes to EXT4.Formatter#672

Open
jglogan wants to merge 11 commits intoapple:mainfrom
jglogan:ext4-journal
Open

Adds journal modes to EXT4.Formatter#672
jglogan wants to merge 11 commits intoapple:mainfrom
jglogan:ext4-journal

Conversation

@jglogan
Copy link
Copy Markdown
Contributor

@jglogan jglogan commented Apr 8, 2026


Due diligence already performed:

@dkovba dkovba requested a review from wlan0 April 8, 2026 23:38
// Clamp to UInt32.max: the kernel caps internal journals at 2^32 blocks
// (per §3.6.4 s_maxlen), and a caller-supplied size large enough to exceed
// that would otherwise trap on the narrowing conversion.
let blocks = size / UInt64(self.blockSize)
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.

Do we need to check that blocks > 0 here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

the numerator and denominator are both UInt64 (self.blockSize is UInt32) so that check would be dead code

Copy link
Copy Markdown
Contributor

@dkovba dkovba Apr 9, 2026

Choose a reason for hiding this comment

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

block would be 0 if size was less than self.blockSize.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

My brain is fried, I thought I was seeing "do we need to check for negative?"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Actually this needs to be bounded at 1024 blocks minimum...

@dkovba dkovba changed the title Adds journal modes to EXT4.Formatter. Adds journal modes to EXT4.Formatter Apr 9, 2026
journalInode.crtimeExtra = now.hi
journalInode.linksCount = 1
journalInode.extraIsize = UInt16(EXT4.ExtraIsize)
journalInode.flags = EXT4.InodeFlag.extents.rawValue
Copy link
Copy Markdown
Contributor

@wlan0 wlan0 Apr 9, 2026

Choose a reason for hiding this comment

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

journal Inodes and file Inodes will be of different sizes if EXT4_HUGE_FILE_FL is omitted here. Without that flag, the kernel accounts for blocks being 512 bytes in size. However, writeExtents works in blockSize units. This will cause accounting mismatches.

The fix is to set InodeFlag.hugeFile flag

@jglogan jglogan force-pushed the ext4-journal branch 2 times, most recently from 2b3215f to 4639b7a Compare April 10, 2026 17:34

// MARK: - Private helpers

private func calculateJournalSize(requestedSize: UInt64?, totalBlocks: UInt32) throws -> UInt32 {
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.

JournalSize needs to account for optimizeBlockGroupLayout

The totalBlocks when this gets called is an estimate based on blockSize and diskSize. However, based on how much data is written, the layout changes (right after close() gets called.

The fix would be to either defer the size validation until after close() knows the real final block count, or to have calculateJournalSize use the post-optimizeBlockGroupLayout block count (i.e., account for the fact that close() will expand the image to fit). The totalBlocks / 2 guard should also be applied consistently to both paths.

Copy link
Copy Markdown
Contributor

@wlan0 wlan0 left a comment

Choose a reason for hiding this comment

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

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.

[Request]: ContainerizationEXT4: support journal modes

3 participants