From: Gao Xiang <xiang.gao@docker.com>
To: linux-erofs@lists.ozlabs.org
Cc: LKML <linux-kernel@vger.kernel.org>, Gao Xiang <xiang.gao@docker.com>
Subject: [PATCH v2] docs: erofs: refine the on-disk overview
Date: Thu, 12 Nov 2026 10:16:15 +0100 [thread overview]
Message-ID: <20261112091615.40264-1-xiang.gao@docker.com> (raw)
In-Reply-To: <20261112021905.36269-1-xiang.gao@docker.com>
The existing on-disk summary mainly describes inode and shared xattr
metadata views, leaving the overall layout and design rationale unclear.
Expand the summary and refine the terminology and wording while keeping
the section a high-level overview.
Assisted-by: chatgpt:gpt-6.1-sol
Signed-off-by: Gao Xiang <xiang.gao@docker.com>
---
changes since v1:
- address Chengyu's comment to describe more about the metabox.
Documentation/filesystems/erofs.rst | 119 +++++++++++++++++++++-------
1 file changed, 90 insertions(+), 29 deletions(-)
diff --git a/Documentation/filesystems/erofs.rst b/Documentation/filesystems/erofs.rst
index 02caf3b061fe..cea781b3cb16 100644
--- a/Documentation/filesystems/erofs.rst
+++ b/Documentation/filesystems/erofs.rst
@@ -171,13 +171,27 @@ Each mounted filesystem will have a directory in /sys/fs/erofs based on its
device name (i.e., /sys/fs/erofs/sda).
(see also Documentation/ABI/testing/sysfs-fs-erofs)
-On-disk details
-===============
+On-disk format
+==============
+
+This section provides a high-level overview. For the latest complete on-disk
+format specification, see:
+
+- https://erofs.docs.kernel.org/en/latest/ondisk/
Summary
-------
-Different from other read-only file systems, an EROFS volume is designed
-to be as simple as possible::
+
+EROFS keeps its on-disk format as simple as possible to minimize the need
+for metadata consistency checks.
+
+The guiding principle is that malformed or deliberately crafted metadata
+may describe a corrupt filesystem, but its effects should remain confined
+to the data and metadata exposed to userspace: garbage filesystems return
+garbage (meta)data to users, and nothing more. Violating this rule is
+unsafe and must be prevented by our on-disk design.
+
+::
|-> aligned with the block size
____________________________________________________________
@@ -185,16 +199,50 @@ to be as simple as possible::
|_|__|_|_____|__________|_____|______|__________|_____|______|
0 +1K
-All data areas should be aligned with the block size, but metadata areas
-may not. All metadata can be now observed in two different spaces (views):
+Apart from the EROFS superblock, which starts at byte offset 1024, metadata
+and data regions have no fixed locations or boundaries and may be interleaved
+throughout the image. As a result, inodes do not need to reside in a fixed
+central table, allowing incremental builds, although the image creator may
+still choose to group all inodes together.
+
+All data except inline data must be aligned to the filesystem block size
+[#unencoded_data]_ to enable efficient block I/O, support memory mapping,
+and avoid unnecessary data copies. Metadata does not require block alignment.
+
+.. [#unencoded_data] Strictly speaking, data refers to unencoded data;
+ encoded inodes are outside the scope of EROFS core metadata.
- 1. Inode metadata space
+EROFS core metadata consists only of the superblock, inodes, and directory
+entries stored in directory inode data. The physical locations of inode
+data are recorded as block numbers to avoid block-alignment checks.
- Each valid inode should be aligned with an inode slot, which is a fixed
- value (32 bytes) and designed to be kept in line with compact inode size.
+Only a few superblock fields, including the root nid (see below), are needed
+to parse the filesystem tree. Most of the remaining fields provide filesystem
+statistics reported to userspace and should not affect the core filesystem
+logic.
- Each inode can be directly found with the following formula:
- inode offset = meta_blkaddr * block_size + 32 * nid
+Encoded inodes, which contain encoded data such as compressed data (including
+compressed directories), use a distinct inode "datalayout" number that allows
+them to be identified or rejected when reading the inode metadata. Support for
+encoded layouts is optional and can be explicitly disabled at runtime if there
+are security concerns about parsing compressed data in the kernel.
+
+There are two metadata views: one for inode metadata and one for shared
+extended attributes. Both can also be located in a special hidden inode
+called "metabox", which provides a unified way to compress inode and xattr
+metadata:
+
+ 1. Inode metadata view
+
+ Each valid inode is aligned to a 32-byte inode slot, matching the
+ size of a compact inode. Inodes can be stored either inside or outside
+ the metabox inode, with a flag in the nid indicating whether they are
+ stored inside.
+
+ For inodes not in the metabox, each inode can be located directly
+ using the following formula::
+
+ inode physical position = meta_blkaddr * block_size + 32 * nid
::
@@ -224,8 +272,8 @@ may not. All metadata can be now observed in two different spaces (views):
|-> aligned with 4B
|-> aligned with 4B
- Inode could be 32 or 64 bytes, which can be distinguished from a common
- field which all inode versions have -- i_format::
+ Inodes can be 32 or 64 bytes, distinguished by the i_format field common
+ to both formats::
__________________ __________________
| i_format | | i_format |
@@ -236,31 +284,44 @@ may not. All metadata can be now observed in two different spaces (views):
| |
|__________________| 64 bytes
- Xattrs, extents, data inline are placed after the corresponding inode with
- proper alignment, and they could be optional for different data mappings.
- _currently_ total 5 data layouts are supported:
+ Xattrs, extents, and inline data follow the corresponding inode with
+ proper alignment. Their presence depends on the inode's datalayout.
+ Five data layouts are currently supported:
== ====================================================================
- 0 flat file data without data inline (no extent);
- 1 fixed-sized output data compression (with non-compacted indexes);
- 2 flat file data with tail packing data inline (no extent);
- 3 fixed-sized output data compression (with compacted indexes, v5.3+);
- 4 chunk-based file (v5.15+).
+ 0 Flat inode data without inline data (no extents);
+ 1 Encoded inode
+ 2 Flat inode data with inline tail data (no extents);
+ 3 Encoded inode (compact indexes)
+ 4 Chunk-based file (v5.15+).
== ====================================================================
- The size of the optional xattrs is indicated by i_xattr_count in inode
- header. Large xattrs or xattrs shared by many different files can be
- stored in shared xattrs metadata rather than inlined right after inode.
+ The size of the optional xattrs is indicated by i_xattr_count in the inode
+ header. Large xattrs or xattrs shared by many files can be stored in
+ shared xattr metadata rather than inlined immediately after the inode.
+
+ For inodes in the metabox, the remaining nid bits identify the inode slot
+ within the metabox's inode address space. This data is read through the
+ metabox inode, with decompression as needed. The metabox inode itself is
+ located outside the metabox and is identified by metabox_nid in the
+ superblock.
- 2. Shared xattrs metadata space
+ 2. Shared xattrs metadata view
- Shared xattrs space is similar to the above inode space, started with
- a specific block indicated by xattr_blkaddr, organized one by one with
- proper align.
+ The shared xattr metadata view is similar to the inode metadata view.
+ It starts at the block indicated by xattr_blkaddr, with entries stored
+ sequentially on 4-byte boundaries. Shared xattrs are stored either all
+ inside or all outside the metabox; this metadata view cannot be selected
+ individually for each entry.
+
+ Each shared xattr can be located using the following formula::
- Each share xattr can also be directly found by the following formula:
xattr offset = xattr_blkaddr * block_size + 4 * xattr_id
+ When COMPAT_SHARED_EA_IN_METABOX feature is enabled, this offset is within
+ the metabox inode's address space. Otherwise, it is a physical position
+ in the filesystem image.
+
::
|-> aligned by 4 bytes
--
2.54.0 (Apple Git-157)
next prev parent reply other threads:[~2026-11-12 9:16 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-12 2:19 [PATCH] " Gao Xiang
2026-11-12 5:32 ` hudsonZhu
2026-11-12 8:35 ` Gao Xiang
2026-11-12 9:16 ` Gao Xiang [this message]
2026-11-12 9:19 ` [PATCH v2] " hudsonZhu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261112091615.40264-1-xiang.gao@docker.com \
--to=xiang.gao@docker.com \
--cc=linux-erofs@lists.ozlabs.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®