Skip to content

Commit 681acbd

Browse files
committed
erofs: add on-disk definition for metadata compression
Filesystem metadata has a high degree of redundancy, so it should compress well in the general case. Although metadata compression can increase overall I/O latency, many users care more about minimized image sizes than extreme runtime performance. Let's implement metadata compression in response to user requests [1]. Actually, it's quite simple to implement metadata compression: since EROFS already supports per-inode compression, we can simply treat a special inode (called `the metabox inode`) as a container for compressed inode metadata. Since EROFS supports multiple algorithms, users can even specify LZ4 for metadata and LZMA for data. To better support incremental builds, the MSB of NIDs indicates where the inode metadata is located: if bit 63 is set, the inode itself should be read from `the metabox inode`. Optionally, shared xattrs can also be kept in `the metabox inode` if COMPAT_SHARED_EA_IN_METABOX is set. [1] https://issues.redhat.com/browse/RHEL-75783 Signed-off-by: Gao Xiang <[email protected]> Acked-by: Chao Yu <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 5e0bf36 commit 681acbd

File tree

2 files changed

+12
-3
lines changed

2 files changed

+12
-3
lines changed

fs/erofs/erofs_fs.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#define EROFS_FEATURE_COMPAT_SB_CHKSUM 0x00000001
1616
#define EROFS_FEATURE_COMPAT_MTIME 0x00000002
1717
#define EROFS_FEATURE_COMPAT_XATTR_FILTER 0x00000004
18+
#define EROFS_FEATURE_COMPAT_SHARED_EA_IN_METABOX 0x00000008
1819

1920
/*
2021
* Any bits that aren't in EROFS_ALL_FEATURE_INCOMPAT should
@@ -31,6 +32,7 @@
3132
#define EROFS_FEATURE_INCOMPAT_DEDUPE 0x00000020
3233
#define EROFS_FEATURE_INCOMPAT_XATTR_PREFIXES 0x00000040
3334
#define EROFS_FEATURE_INCOMPAT_48BIT 0x00000080
35+
#define EROFS_FEATURE_INCOMPAT_METABOX 0x00000100
3436
#define EROFS_ALL_FEATURE_INCOMPAT \
3537
((EROFS_FEATURE_INCOMPAT_48BIT << 1) - 1)
3638

@@ -46,7 +48,7 @@ struct erofs_deviceslot {
4648
};
4749
#define EROFS_DEVT_SLOT_SIZE sizeof(struct erofs_deviceslot)
4850

49-
/* erofs on-disk super block (currently 128 bytes) */
51+
/* erofs on-disk super block (currently 144 bytes at maximum) */
5052
struct erofs_super_block {
5153
__le32 magic; /* file system magic number */
5254
__le32 checksum; /* crc32c to avoid unexpected on-disk overlap */
@@ -82,7 +84,9 @@ struct erofs_super_block {
8284
__u8 reserved[3];
8385
__le32 build_time; /* seconds added to epoch for mkfs time */
8486
__le64 rootnid_8b; /* (48BIT on) nid of root directory */
85-
__u8 reserved2[8];
87+
__le64 reserved2;
88+
__le64 metabox_nid; /* (METABOX on) nid of the metabox inode */
89+
__le64 reserved3; /* [align to extslot 1] */
8690
};
8791

8892
/*
@@ -267,6 +271,9 @@ struct erofs_inode_chunk_index {
267271
__le32 startblk_lo; /* starting block number of this chunk */
268272
};
269273

274+
#define EROFS_DIRENT_NID_METABOX_BIT 63
275+
#define EROFS_DIRENT_NID_MASK (BIT_ULL(EROFS_DIRENT_NID_METABOX_BIT) - 1)
276+
270277
/* dirent sorts in alphabet order, thus we can do binary search */
271278
struct erofs_dirent {
272279
__le64 nid; /* node number */
@@ -434,7 +441,7 @@ static inline void erofs_check_ondisk_layout_definitions(void)
434441
.h_clusterbits = 1 << Z_EROFS_FRAGMENT_INODE_BIT
435442
};
436443

437-
BUILD_BUG_ON(sizeof(struct erofs_super_block) != 128);
444+
BUILD_BUG_ON(sizeof(struct erofs_super_block) != 144);
438445
BUILD_BUG_ON(sizeof(struct erofs_inode_compact) != 32);
439446
BUILD_BUG_ON(sizeof(struct erofs_inode_extended) != 64);
440447
BUILD_BUG_ON(sizeof(struct erofs_xattr_ibody_header) != 12);

fs/erofs/internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,10 @@ EROFS_FEATURE_FUNCS(fragments, incompat, INCOMPAT_FRAGMENTS)
227227
EROFS_FEATURE_FUNCS(dedupe, incompat, INCOMPAT_DEDUPE)
228228
EROFS_FEATURE_FUNCS(xattr_prefixes, incompat, INCOMPAT_XATTR_PREFIXES)
229229
EROFS_FEATURE_FUNCS(48bit, incompat, INCOMPAT_48BIT)
230+
EROFS_FEATURE_FUNCS(metabox, incompat, INCOMPAT_METABOX)
230231
EROFS_FEATURE_FUNCS(sb_chksum, compat, COMPAT_SB_CHKSUM)
231232
EROFS_FEATURE_FUNCS(xattr_filter, compat, COMPAT_XATTR_FILTER)
233+
EROFS_FEATURE_FUNCS(shared_ea_in_metabox, compat, COMPAT_SHARED_EA_IN_METABOX)
232234

233235
/* atomic flag definitions */
234236
#define EROFS_I_EA_INITED_BIT 0

0 commit comments

Comments
 (0)