Skip to content

Optimize the ext4 data layout in userspace conversion - #475

Open
BigVan wants to merge 1 commit into
containerd:mainfrom
BigVan:adjust_data_layout
Open

BigVan wants to merge 1 commit into
containerd:mainfrom
BigVan:adjust_data_layout

Conversation

@BigVan

@BigVan BigVan commented Oct 27, 2026

Copy link
Copy Markdown
Member

overlaybd-apply wrote regular files through ext4, so in a LSMT layer the file data was interleaved with the fs metadata that ext4 wrote back whenever its cache flushed, scattering fsmeta all over the data area.

A plain LSMT layer is now converted in two pas/ses. The tar stream is read once, appending the padded data of every regular file to the upper data file in tar order and spooling the headers to a temporary file, with each file's data offset recorded in devmajor. Then the ext4 fs is created and the headers are replayed metadata-only, as TurboOCI does, mapping each file's blocks to its staged data through RemoteData. The mappings are applied after the fs is synced, so a metadata block reused for file data cannot be written back over it, and the tail of a reused last block is zeroed. overlaybd-commit --seal then appends the index and trailer in place, giving

Header | file data | fs metadata | index | Trailer

What this PR does / why we need it:

Which issue(s) this PR fixes (optional, in fixes #<issue number>(, fixes #<issue_number>, ...) format, will close the issue(s) when PR gets merged):
Fixes #

Please check the following list:

  • Does the affected code have corresponding tests, e.g. unit test, E2E test?
  • Does this change require a documentation update?
  • Does this introduce breaking changes that would require an announcement or bumping the major version?
  • Do all new files have an appropriate license header?

overlaybd-apply wrote regular files through ext4, so in a LSMT layer
the file data was interleaved with the fs metadata that ext4 wrote
back whenever its cache flushed, scattering fsmeta all over the
data area.

A plain LSMT layer is now converted in two pas/ses. The tar
stream is read once, appending the padded data of every regular file to
the upper data file in tar order and spooling the headers to a
temporary file, with each file's data offset recorded in devmajor. Then
the ext4 fs is created and the headers are replayed metadata-only, as
TurboOCI does, mapping each file's blocks to its staged data through
RemoteData. The mappings are applied after the fs is synced, so a
metadata block reused for file data cannot be written back over it, and
the tail of a reused last block is zeroed. `overlaybd-commit --seal`
then appends the index and trailer in place, giving

    Header | file data | fs metadata | index | Trailer

Signed-off-by: Yifan Yuan <tuji.yyf@outlook.com>
@BigVan BigVan assigned yuchen0cc and unassigned yuchen0cc Oct 27, 2026
@BigVan
BigVan requested review from liulanzheng and a balanced review from Copilot October 27, 2026 15:36

Copilot AI 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.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Copilot review overview

4 open issues
What changed in this PR

Improves overlaybd-apply ext4 layer conversion by staging regular-file payload ahead of ext4 metadata, then replaying headers metadata-only and mapping file blocks to the staged payload to avoid metadata/data interleaving.

Changes:

  • Add a two-pass “stage payload + replay metadata” extraction flow for plain LSMT append layers.
  • Introduce FsMetaFile for sparse staging and compact appending of live ext4 metadata blocks.
  • Extend tar extraction and LSMT layer support to defer and then apply RemoteData mappings, plus add comprehensive tests and documentation.
File Description
src/​tools/​overlaybd-apply.cpp Orchestrates staging/replay flow and temp header/fsmeta spooling.
src/​overlaybd/​tar/​libtar.h Adds staged extraction APIs and deferred mapping bookkeeping.
src/​overlaybd/​tar/​libtar.cpp Implements stage_tar, extract_staged, pending mappings, and block-tail handling.
src/​overlaybd/​tar/​whiteout.cpp Routes unlinks through new helper to keep pending mappings consistent.
src/​overlaybd/​tar/​fsmeta_file.h Declares FsMetaFile virtual file wrapper for fs metadata staging.
src/​overlaybd/​tar/​fsmeta_file.cpp Implements staging reads/writes, dirty tracking, and compact commit into base.
src/​overlaybd/​tar/​test/​test.cpp Adds staged extraction + fsmeta tests and layout assertions.
src/​overlaybd/​lsmt/​file.h Exposes can_map_staged_data() capability query.
src/​overlaybd/​lsmt/​file.cpp Adds staged RemoteData validation/mapping and improves sealed index write padding.
src/​overlaybd/​lsmt/​test/​test.cpp Adds staging/mapping behavior tests (reopen, seal, stacking, rejects).
docs/​apply-data-layout.md Documents the new ext4 userspace conversion layout and rationale (EN).
docs/​apply-data-layout_zh.md Documents the new ext4 userspace conversion layout and rationale (ZH).
docs/​README.md Mentions the ext4 optimized layout and links to the new doc.
CMake/​Findphoton.cmake Forces Photon to use shared liburing build and adds dependency ordering.

Review effort: Lite

Comment on lines +154 to +155
auto end = (offset + count + BLOCK_SIZE - 1) / BLOCK_SIZE;
for (size_t block = offset / BLOCK_SIZE; block < end; block++) {
Comment on lines +470 to 479
photon::fs::fiemap probe(0, size, 0);
if (fout->fiemap(&probe) != 0) {
return -1;
}
std::vector<char> mem(sizeof(photon::fs::fiemap) +
probe.fm_mapped_extents * sizeof(photon::fs::fiemap_extent));
auto fie = new (mem.data()) photon::fs::fiemap(0, size, probe.fm_mapped_extents);
if (fout->fiemap(fie) != 0) {
return -1;
}
Comment on lines +166 to +168
if (target->pwrite(buf, buffered, base + staged) != (ssize_t)buffered) {
LOG_ERRNO_RETURN(EIO, -1, "failed to stage ` bytes", buffered);
}
Comment on lines +241 to +242
auto tar = new UnTar(src_file, target, 0, 4096, base_file, gen_turboOCI);
if (tar->extract_all() < 0) {
@BigVan

BigVan commented Oct 30, 2026

Copy link
Copy Markdown
Member Author

@WaberZhuang PTAL

This branch has not been deployed

No deployments
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.

3 participants