Skip to content

feat(ext4): enable inline_data on rootfs mkfs#2563

Merged
ValentaTomas merged 2 commits into
mainfrom
feat/ext4-inline-data
May 5, 2026
Merged

feat(ext4): enable inline_data on rootfs mkfs#2563
ValentaTomas merged 2 commits into
mainfrom
feat/ext4-inline-data

Conversation

@ValentaTomas

@ValentaTomas ValentaTomas commented May 5, 2026

Copy link
Copy Markdown
Member

Enable ext4 inline_data on rootfs mkfs. Files <~160 B (with default 256 B inodes) live inside the inode instead of allocating a 4 KiB data block — shrinks rootfs diff for small-file churn and improves locality (dirties cluster on inode-table blocks).

mkfs-time only. Affects newly-built bases. No semantic change for guest workloads.

@cursor

cursor Bot commented May 5, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Changes the ext4 feature set used at image build time, which can impact compatibility with older kernels or tooling when mounting/repairing new images. Scope is limited to newly created rootfs images and does not affect existing ones.

Overview
This changes rootfs creation to pass the ext4 inline_data feature to mkfs.ext4, so very small files can be stored inside inodes instead of consuming separate data blocks. It also clarifies in-code comments about which ext4 features are explicitly toggled versus left as defaults.

Reviewed by Cursor Bugbot for commit b48794e. Bugbot is set up for automated code reviews on this repo. Configure here.

@codecov

codecov Bot commented May 5, 2026

Copy link
Copy Markdown

❌ 3 Tests Failed:

Tests completed Failed Passed Skipped
2355 3 2352 5
View the full list of 3 ❄️ flaky test(s)
github.com/e2b-dev/infra/tests/integration/internal/tests/api/metrics::TestTeamMetrics

Flake rate in main: 55.56% (Passed 4 times, Failed 5 times)

Stack Traces | 2.54s run time
=== RUN   TestTeamMetrics
=== PAUSE TestTeamMetrics
=== CONT  TestTeamMetrics
    team_metrics_test.go:61: 
        	Error Trace:	.../api/metrics/team_metrics_test.go:61
        	Error:      	Should be true
        	Test:       	TestTeamMetrics
        	Messages:   	MaxConcurrentSandboxes should be >= 0
--- FAIL: TestTeamMetrics (2.54s)
github.com/e2b-dev/infra/tests/integration/internal/tests/api/sandboxes::TestUpdateNetworkConfig

Flake rate in main: 57.14% (Passed 6 times, Failed 8 times)

Stack Traces | 25.5s run time
=== RUN   TestUpdateNetworkConfig
=== PAUSE TestUpdateNetworkConfig
=== CONT  TestUpdateNetworkConfig
--- FAIL: TestUpdateNetworkConfig (25.48s)
github.com/e2b-dev/infra/tests/integration/internal/tests/api/sandboxes::TestUpdateNetworkConfig/pause_resume_preserves_allow_internet_access_false

Flake rate in main: 50.00% (Passed 6 times, Failed 6 times)

Stack Traces | 0.63s run time
=== RUN   TestUpdateNetworkConfig/pause_resume_preserves_allow_internet_access_false
Executing command curl in sandbox if0ej2f2uotp0ig2vmrs8
    sandbox_network_update_test.go:372: Command [curl] output: event:{start:{pid:1356}}
    sandbox_network_update_test.go:372: Command [curl] output: event:{end:{exit_code:35 exited:true status:"exit status 35" error:"exit status 35"}}
Executing command curl in sandbox if0ej2f2uotp0ig2vmrs8
    sandbox_network_update_test.go:372: Command [curl] output: event:{start:{pid:1357}}
    sandbox_network_update_test.go:372: Command [curl] output: event:{end:{exit_code:35 exited:true status:"exit status 35" error:"exit status 35"}}
    sandbox_network_update_test.go:391: Command [curl] output: event:{start:{pid:1358}}
    sandbox_network_update_test.go:391: Command [curl] output: event:{data:{stdout:"HTTP/2 302 \r\nx-content-type-options: nosniff\r\nlocation: https://dns.google/\r\ndate: Tue, 05 May 2026 01:58:39 GMT\r\ncontent-type: text/html; charset=UTF-8\r\nserver: HTTP server (unknown)\r\ncontent-length: 216\r\nx-xss-protection: 0\r\nx-frame-options: SAMEORIGIN\r\nalt-svc: h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000\r\n\r\n"}}
    sandbox_network_update_test.go:391: Command [curl] output: event:{end:{exited:true status:"exit status 0"}}
    sandbox_network_update_test.go:391: Command [curl] completed successfully in sandbox if0ej2f2uotp0ig2vmrs8
    sandbox_network_update_test.go:391: 
        	Error Trace:	.../api/sandboxes/sandbox_network_out_test.go:74
        	            				.../api/sandboxes/sandbox_network_update_test.go:60
        	            				.../api/sandboxes/sandbox_network_update_test.go:391
        	Error:      	An error is expected but got nil.
        	Test:       	TestUpdateNetworkConfig/pause_resume_preserves_allow_internet_access_false
        	Messages:   	https://8.8.8.8 should be blocked
--- FAIL: TestUpdateNetworkConfig/pause_resume_preserves_allow_internet_access_false (0.63s)

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request enables the inline_data feature for ext4 filesystem creation to optimize storage for small files and improve diff locality. I have no feedback to provide.

@ValentaTomas ValentaTomas requested a review from arkamar May 5, 2026 01:17
@ValentaTomas ValentaTomas marked this pull request as ready for review May 5, 2026 01:18
@qodo-code-review

Copy link
Copy Markdown

PR Reviewer Guide 🔍

Warning

/review is deprecated. Use /agentic_review instead (removed after 2026-05-31).

Here are some key observations to aid the review process:

⚡ Recommended focus areas for review

Build Break

Enabling the ext4 inline_data feature may cause mkfs.ext4 to fail on build hosts with older e2fsprogs that don’t recognize/support this feature, which would break rootfs creation unless there’s a version gate or a fallback path.

cmd := exec.CommandContext(ctx,
	"mkfs.ext4",
	"-O", strings.Join([]string{
		// resize_inode, sparse_super (required for resize_inode), has_journal,
		// and metadata_csum are kept as defaults.
		"^64bit",
		"^dir_index",
		"^dir_nlink",
		"ext_attr",
		"extent",
		"extra_isize",
		"filetype",
		"flex_bg",
		"huge_file",
		// inline_data stores file contents <~160 B (with 256 B inodes) inside
		// the inode itself, avoiding a separate 4 KiB data block per tiny file.
		// Shrinks rootfs diff size for small-file churn (pidfiles, /run state,
		// utmp, package metadata, etc.) and improves diff locality since dirty
		// blocks cluster on inode-table blocks instead of scattering across the
		// data region.
		"inline_data",
		"large_file",
		"sparse_super2",
	}, ","),

Tiny files (<~160 B with default 256 B inodes) now live inside the
inode instead of getting their own 4 KiB data block. Reduces rootfs
diff size for small-file churn (pidfiles, /run state, utmp, package
metadata) and improves locality since dirty blocks cluster on
inode-table blocks rather than scattering across the data region —
fewer GCS chunks per cold resume.

mkfs-time only; applies to newly-built bases. Existing diff/discard
behaviour unchanged for files above the inline threshold.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM — small, well-scoped feature flag addition; the inline bug is a comment-freshness nit.

Extended reasoning...

Overview

The PR adds a single feature flag (inline_data) to the mkfs.ext4 invocation in packages/orchestrator/pkg/template/build/core/filesystem/ext4.go. The change is two lines (one for the feature, one for the explanatory comment) and only affects newly-built rootfs templates at mkfs time — existing template images are unaffected.

Security risks

None. This is a filesystem feature flag for an internal rootfs build step. inline_data is a long-standing ext4 feature (Linux ≥3.8, well past the kernel versions used by Firecracker here) that simply lets small file contents live in the inode rather than a separate data block. No auth, crypto, network, or untrusted-input surface is touched.

Level of scrutiny

Low. This is a mechanical, single-flag config change to a build-time tool invocation, with a clear performance/storage rationale (small-file churn no longer dirties a fresh 4 KiB data block per file, improving diff locality for layered rootfs storage). It compounds with prior PR #2423 in a contained way. The cursor and qodo bots flagged generic INCOMPAT/old-e2fsprogs concerns, but the build/runtime environments are controlled and the feature has been mainline since 2013.

Other factors

The only finding from the bug-hunting pass is a documentation nit — the PR description claims a stale tar2ext4 comment was removed, but the diff is purely additive and the old comment block at lines 45-47 remains. Worth fixing for accuracy, but not blocking. Codecov reports all modified lines covered and all tests passing.

Comment thread packages/orchestrator/pkg/template/build/core/filesystem/ext4.go
oci.ToExt4 no longer uses the tar2ext4 binary, and adding inline_data
means the list no longer matches tar2ext4 defaults anyway. Replace the
comment with a short note describing what the explicit list does
(toggle on top of mkfs defaults).
@ValentaTomas ValentaTomas removed the request for review from jakubno May 5, 2026 01:49
@ValentaTomas ValentaTomas merged commit ae68b80 into main May 5, 2026
48 checks passed
@ValentaTomas ValentaTomas deleted the feat/ext4-inline-data branch May 5, 2026 02:50
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.

2 participants