Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions CMake/Findphoton.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ include(FetchContent)
set(FETCHCONTENT_QUIET false)
set(PHOTON_ENABLE_EXTFS ON)

# Runloop: patch Photon's ext4 mkfs to enable uninitialized block groups
# (gdt_csum). This lets an offline resize2fs grow of a devbox rootfs mark new
# inode tables uninitialized instead of zeroing them — a near-instant grow with
# minimal writes into the layered (COW) block format.
# Runloop: patch Photon's ext4 mkfs to lay out a devbox rootfs for the layered
# (COW) block format it lives on. The image is baked at one size and grown to
# the devbox's disk size by an offline resize2fs before first mount, so the
# feature set is chosen to make that grow write as few blocks as possible while
# leaving the result checksummed and correct.
# Idempotent: skips if the patch is already applied (reverse-check succeeds).
set(_photon_mkfs_patch "${CMAKE_CURRENT_LIST_DIR}/patches/photon-v0.6.17-ext4-uninit-bg.patch")
set(_photon_mkfs_patch "${CMAKE_CURRENT_LIST_DIR}/patches/photon-v0.6.17-ext4-rootfs-format.patch")
FetchContent_Declare(
photon
GIT_REPOSITORY https://github.com/alibaba/PhotonLibOS.git
Expand Down
89 changes: 89 additions & 0 deletions CMake/patches/photon-v0.6.17-ext4-rootfs-format.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
diff --git a/fs/extfs/mkfs.cpp b/fs/extfs/mkfs.cpp
index 0195ae5..60a0aa7 100644
--- a/fs/extfs/mkfs.cpp
+++ b/fs/extfs/mkfs.cpp
@@ -60,11 +60,19 @@ int do_mkfs(io_manager manager, size_t size, char *uuid) {
memset(&fs_param, 0, sizeof(struct ext2_super_block));
fs_param.s_rev_level = 1;

+ // Runloop: this image is grown to the target disk size by an offline
+ // resize2fs before it is ever mounted, and it lives on a layered (COW)
+ // block format where every block the grow writes becomes a new block. The
+ // feature set below is chosen to keep that grow as close to free as
+ // possible.
ext2fs_set_feature_64bit(&fs_param);
ext2fs_set_feature_sparse_super(&fs_param);
- ext2fs_set_feature_sparse_super2(&fs_param);
ext2fs_set_feature_filetype(&fs_param);
- ext2fs_set_feature_resize_inode(&fs_param);
+ // Runloop: meta_bg rather than resize_inode. resize_inode reserves a
+ // contiguous GDT area that resize2fs rewrites in full on every grow —
+ // megabytes of COW churn regardless of how far the filesystem grows.
+ // meta_bg reserves nothing and extends the descriptor table in place.
+ ext2fs_set_feature_meta_bg(&fs_param);
ext2fs_set_feature_dir_index(&fs_param);
ext2fs_set_feature_xattr(&fs_param);
ext2fs_set_feature_dir_nlink(&fs_param);
@@ -73,10 +81,23 @@ int do_mkfs(io_manager manager, size_t size, char *uuid) {
ext2fs_set_feature_flex_bg(&fs_param);
ext2fs_set_feature_extents(&fs_param);
ext2fs_set_feature_extra_isize(&fs_param);
+ // Runloop: metadata_csum marks the block groups a grow appends as
+ // uninitialized, so their inode tables are never zeroed — the grow writes
+ // descriptors and nothing else — and checksums every metadata structure,
+ // which is the only damage signal available on a filesystem carrying no
+ // journal. It seeds those checksums from s_uuid, so the seed must be
+ // re-derived once the real UUID is installed below.
+ ext2fs_set_feature_metadata_csum(&fs_param);
+ // Runloop: sparse_super2 must stay off. It places its second backup
+ // superblock in the last block group; growing the filesystem relocates
+ // that backup and frees one block too many, handing out the group's own
+ // block bitmap as free space.

fs_param.s_log_cluster_size = fs_param.s_log_block_size = 2;
fs_param.s_desc_size = EXT2_MIN_DESC_SIZE_64BIT;
- fs_param.s_log_groups_per_flex = 0;
+ // Runloop: 16 groups per flex group, keeping bitmaps and inode tables
+ // clustered rather than one copy per group at a fixed offset inside it.
+ fs_param.s_log_groups_per_flex = 4;
fs_param.s_inode_size = inode_size;

ext2fs_blocks_count_set(&fs_param, blocks_count);
@@ -84,8 +105,6 @@ int do_mkfs(io_manager manager, size_t size, char *uuid) {
fs_param.s_inodes_count = (n > UINT_MAX) ? UINT_MAX : n;

ext2fs_r_blocks_count_set(&fs_param, reserved_ratio * ext2fs_blocks_count(&fs_param));
- fs_param.s_backup_bgs[0] = 1;
- fs_param.s_backup_bgs[1] = ~0;

ext2_filsys fs;
// init superblock
@@ -96,6 +115,13 @@ int do_mkfs(io_manager manager, size_t size, char *uuid) {

uuid4_parse(uuid, (char*)(fs->super->s_uuid));
uuid4_parse(uuid, (char*)(fs_param.s_hash_seed));
+ // Runloop: finish what metadata_csum needs and ext2fs_initialize does not
+ // do, before anything below writes a checksummed structure. The algorithm
+ // is not implied by the feature bit — a superblock left at type 0 is
+ // rejected as an unknown checksum on open — and the seed is derived from
+ // s_uuid, which ext2fs_initialize saw as zeroes.
+ fs->super->s_checksum_type = EXT2_CRC32C_CHKSUM;
+ ext2fs_init_csum_seed(fs);
fs->super->s_kbytes_written = 1;
fs->super->s_def_hash_version = EXT2_HASH_HALF_MD4;
fs->super->s_max_mnt_count = -1;
@@ -121,9 +147,11 @@ int do_mkfs(io_manager manager, size_t size, char *uuid) {
ext2fs_inode_alloc_stats2(fs, i, +1, 0);
ext2fs_mark_ib_dirty(fs);
// create resize inode
- ret = ext2fs_create_resize_inode(fs);
- if (ret) {
- LOG_ERRNO_RETURN(0, -1, "error creating resize inode ", VALUE(ret));
+ if (ext2fs_has_feature_resize_inode(fs->super)) {
+ ret = ext2fs_create_resize_inode(fs);
+ if (ret) {
+ LOG_ERRNO_RETURN(0, -1, "error creating resize inode ", VALUE(ret));
+ }
}

ret = ext2fs_close_free(&fs);
16 changes: 0 additions & 16 deletions CMake/patches/photon-v0.6.17-ext4-uninit-bg.patch

This file was deleted.

Loading