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] docs: erofs: refine the on-disk overview
Date: Thu, 12 Nov 2026 03:19:05 +0100 [thread overview]
Message-ID: <20261112021905.36269-1-xiang.gao@docker.com> (raw)
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>
---
Documentation/filesystems/erofs.rst | 100 ++++++++++++++++++++--------
1 file changed, 72 insertions(+), 28 deletions(-)
diff --git a/Documentation/filesystems/erofs.rst b/Documentation/filesystems/erofs.rst
index 02caf3b061fe..0633e69aa71e 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,15 +199,45 @@ 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.
+
+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.
+
+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.
+
+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 space
+ 1. Inode metadata view
- 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.
+ Each valid inode is aligned to a 32-byte inode slot, matching the
+ size of a compact inode.
- Each inode can be directly found with the following formula:
+ Each inode can be located directly using the following formula:
inode offset = meta_blkaddr * block_size + 32 * nid
::
@@ -224,8 +268,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,29 +280,29 @@ 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.
- 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 with proper alignment.
- Each share xattr can also be directly found by the following formula:
+ Each shared xattr can be located directly using the following formula:
xattr offset = xattr_blkaddr * block_size + 4 * xattr_id
::
--
2.54.0 (Apple Git-157)
reply other threads:[~2026-11-12 2:19 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20261112021905.36269-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®