Chunk-based Inode Layout#
The chunk-based inode layout splits inode data into fixed-size chunks, each mapped to a contiguous range of physical filesystem blocks. This format supports data deduplication and multi-device storage, allowing efficient data sharing among different inodes and images.
Superblock Extension for Chunk-based Inodes and Multiple Devices#
The core superblock format is defined in Superblock. This section lists the extended fields dedicated to chunk-based inode support and multi-device addressing features.
Offset |
Size |
Type |
Name |
Description |
|---|---|---|---|---|
0x50 |
4 |
|
|
|
0x56 |
2 |
|
|
Number of extra devices in addition to the primary one. Valid when |
0x58 |
2 |
|
|
Starting slot number of the device table on the primary device. The byte offset is |
Inode Fields for Chunked Inodes#
The full compact and extended inode layouts are defined in Inodes. For chunk-based inodes, both inode variants share the same feature-specific fields:
Offset |
Size |
Type |
Name |
Description |
|---|---|---|---|---|
0x00 |
2 |
|
|
Inode format hints; |
0x10 |
4 |
|
|
Chunk info summary described below |
Inode Data Layout for Chunked Inodes#
The following new data layout of an inode is encoded in bits 1–3 of i_format.
EROFS_INODE_CHUNK_BASED (4)#
The entire inode data is split into fixed-size chunks, each occupying consecutive
physical blocks. Requires EROFS_FEATURE_INCOMPAT_CHUNKED_FILE. i_u encodes a
chunk info summary and an array of per-chunk address entries follows the inode body.
Chunk-based Structures#
When the data layout is EROFS_INODE_CHUNK_BASED, the i_u field (4 bytes at
inode offset 0x10) is interpreted as a chunk info summary:
Chunk Info Summary#
Bits |
Width |
Description |
|---|---|---|
0–4 |
5 |
|
5 |
1 |
|
6 |
1 |
48-bit layout specific; ignored for basic chunk-based inodes |
7–31 |
25 |
Reserved; must be 0 |
Per-chunk extent entries are stored immediately after the core on-disk inode and
the inode xattr region. The number of entries is ⌈i_size / chunk_size⌉.
Chunk Entry Formats#
The EROFS_CHUNK_FORMAT_INDEXES bit in the chunk info summary selects one of two
per-chunk entry formats:
Block Map Entry (4 bytes)#
When EROFS_CHUNK_FORMAT_INDEXES is not set, each chunk is described by a
single 32-bit block address entry.
Without a device table, this entry is a primary-device block address.
With EROFS_FEATURE_INCOMPAT_DEVICE_TABLE, it is interpreted in
the unified address space and can resolve to either the primary or an extra device.
Offset |
Size |
Type |
Name |
Description |
|---|---|---|---|---|
0x00 |
4 |
|
|
Starting block address of this chunk |
Chunk Index Entry (8 bytes)#
When EROFS_CHUNK_FORMAT_INDEXES is set, each chunk is described by an 8-byte
record that supports multi-device addressing.
Offset |
Size |
Type |
Name |
Description |
|---|---|---|---|---|
0x00 |
2 |
|
dontcare |
48-bit layout specific; ignored for basic chunk-based inodes |
0x02 |
2 |
|
|
Device selector. |
0x04 |
4 |
|
|
32-bit starting block address; interpretation depends on |
When device_id is 0, startblk is interpreted exactly like a
Block Map Entry (4 bytes):
it is an absolute block address in the unified address space. When
device_id is non-zero, it directly selects an extra device and startblk
is interpreted as a block address on that device. See
Block Address Resolution for Chunk-based Inodes.
Multi-device Support#
Device Table#
This section applies when EROFS_FEATURE_INCOMPAT_DEVICE_TABLE is set.
When EROFS_FEATURE_INCOMPAT_DEVICE_TABLE is set, the extra_devices superblock
field gives the number of additional block devices. They are described by an array
of 128-byte device slot records stored on the primary device. The first record
begins at byte offset devt_slotoff * 128.
Each record contains:
Offset |
Size |
Type |
Name |
Description |
|---|---|---|---|---|
0x00 |
64 |
|
|
User-specific identifier: The kernel never parses it in any form |
0x40 |
4 |
|
|
32-bit total block count of this device |
0x44 |
4 |
|
|
32-bit unified starting block address of this device |
0x48 |
4 |
|
dontcare |
48-bit layout specific; ignored for basic chunk-based inodes |
0x4C |
52 |
|
reserved |
Reserved; must be 0 |
Block Address Resolution for Chunk-based Inodes#
Chunk Index Entry#
When the chunk index entry format is used, device_id controls how
startblk is interpreted:
device_id = 0:startblkis an absolute block address in the unified address space; see Block Map Entry for details.device_id = N(1 ≤ N ≤extra_devices):startblkis a block address on extra device N, whose record begins at byte offset(devt_slotoff + N - 1) * 128on the primary device.
Block Map Entry#
The simple block map entry format has no device_id field. Instead, startblk
is an absolute block address in the unified address space, and the reader uses
uniaddr from the device table to identify the target device: it finds the
slot i whose range [uniaddr[i], uniaddr[i] + blocks[i]) contains
startblk, then derives the intra-device block address as
startblk − uniaddr[i]. Chunk index entries with device_id = 0 use this
same interpretation.