File Index
Files and directories
Sign in
FILE

erofs_fs.h

File preview with syntax highlighting.

linux-6.19.14/fs/erofs/erofs_fs.h C
  1/* SPDX-License-Identifier: MIT */
  2/*
  3 * EROFS (Enhanced ROM File System) on-disk format definition
  4 *
  5 * Copyright (C) 2017-2018 HUAWEI, Inc.
  6 *             https://www.huawei.com/
  7 * Copyright (C) 2021, Alibaba Cloud
  8 */
  9#ifndef __EROFS_FS_H
 10#define __EROFS_FS_H
 11
 12/* to allow for x86 boot sectors and other oddities. */
 13#define EROFS_SUPER_OFFSET      1024
 14
 15#define EROFS_FEATURE_COMPAT_SB_CHKSUM			0x00000001
 16#define EROFS_FEATURE_COMPAT_MTIME			0x00000002
 17#define EROFS_FEATURE_COMPAT_XATTR_FILTER		0x00000004
 18#define EROFS_FEATURE_COMPAT_SHARED_EA_IN_METABOX	0x00000008
 19#define EROFS_FEATURE_COMPAT_PLAIN_XATTR_PFX		0x00000010
 20
 21
 22/*
 23 * Any bits that aren't in EROFS_ALL_FEATURE_INCOMPAT should
 24 * be incompatible with this kernel version.
 25 */
 26#define EROFS_FEATURE_INCOMPAT_ZERO_PADDING	0x00000001
 27#define EROFS_FEATURE_INCOMPAT_COMPR_CFGS	0x00000002
 28#define EROFS_FEATURE_INCOMPAT_BIG_PCLUSTER	0x00000002
 29#define EROFS_FEATURE_INCOMPAT_CHUNKED_FILE	0x00000004
 30#define EROFS_FEATURE_INCOMPAT_DEVICE_TABLE	0x00000008
 31#define EROFS_FEATURE_INCOMPAT_COMPR_HEAD2	0x00000008
 32#define EROFS_FEATURE_INCOMPAT_ZTAILPACKING	0x00000010
 33#define EROFS_FEATURE_INCOMPAT_FRAGMENTS	0x00000020
 34#define EROFS_FEATURE_INCOMPAT_DEDUPE		0x00000020
 35#define EROFS_FEATURE_INCOMPAT_XATTR_PREFIXES	0x00000040
 36#define EROFS_FEATURE_INCOMPAT_48BIT		0x00000080
 37#define EROFS_FEATURE_INCOMPAT_METABOX		0x00000100
 38#define EROFS_ALL_FEATURE_INCOMPAT		\
 39	((EROFS_FEATURE_INCOMPAT_METABOX << 1) - 1)
 40
 41#define EROFS_SB_EXTSLOT_SIZE	16
 42
 43struct erofs_deviceslot {
 44	u8 tag[64];		/* digest(sha256), etc. */
 45	__le32 blocks_lo;	/* total blocks count of this device */
 46	__le32 uniaddr_lo;	/* unified starting block of this device */
 47	__le32 blocks_hi;	/* total blocks count MSB */
 48	__le16 uniaddr_hi;	/* unified starting block MSB */
 49	u8 reserved[50];
 50};
 51#define EROFS_DEVT_SLOT_SIZE	sizeof(struct erofs_deviceslot)
 52
 53/* erofs on-disk super block (currently 144 bytes at maximum) */
 54struct erofs_super_block {
 55	__le32 magic;           /* file system magic number */
 56	__le32 checksum;        /* crc32c to avoid unexpected on-disk overlap */
 57	__le32 feature_compat;
 58	__u8 blkszbits;         /* filesystem block size in bit shift */
 59	__u8 sb_extslots;	/* superblock size = 128 + sb_extslots * 16 */
 60	union {
 61		__le16 rootnid_2b;	/* nid of root directory */
 62		__le16 blocks_hi;	/* (48BIT on) blocks count MSB */
 63	} __packed rb;
 64	__le64 inos;            /* total valid ino # (== f_files - f_favail) */
 65	__le64 epoch;		/* base seconds used for compact inodes */
 66	__le32 fixed_nsec;	/* fixed nanoseconds for compact inodes */
 67	__le32 blocks_lo;	/* blocks count LSB */
 68	__le32 meta_blkaddr;	/* start block address of metadata area */
 69	__le32 xattr_blkaddr;	/* start block address of shared xattr area */
 70	__u8 uuid[16];          /* 128-bit uuid for volume */
 71	__u8 volume_name[16];   /* volume name */
 72	__le32 feature_incompat;
 73	union {
 74		/* bitmap for available compression algorithms */
 75		__le16 available_compr_algs;
 76		/* customized sliding window size instead of 64k by default */
 77		__le16 lz4_max_distance;
 78	} __packed u1;
 79	__le16 extra_devices;	/* # of devices besides the primary device */
 80	__le16 devt_slotoff;	/* startoff = devt_slotoff * devt_slotsize */
 81	__u8 dirblkbits;	/* directory block size in bit shift */
 82	__u8 xattr_prefix_count;	/* # of long xattr name prefixes */
 83	__le32 xattr_prefix_start;	/* start of long xattr prefixes */
 84	__le64 packed_nid;	/* nid of the special packed inode */
 85	__u8 xattr_filter_reserved; /* reserved for xattr name filter */
 86	__u8 reserved[3];
 87	__le32 build_time;	/* seconds added to epoch for mkfs time */
 88	__le64 rootnid_8b;	/* (48BIT on) nid of root directory */
 89	__le64 reserved2;
 90	__le64 metabox_nid;     /* (METABOX on) nid of the metabox inode */
 91	__le64 reserved3;	/* [align to extslot 1] */
 92};
 93
 94/*
 95 * EROFS inode datalayout (i_format in on-disk inode):
 96 * 0 - uncompressed flat inode without tail-packing inline data:
 97 * 1 - compressed inode with non-compact indexes:
 98 * 2 - uncompressed flat inode with tail-packing inline data:
 99 * 3 - compressed inode with compact indexes:
100 * 4 - chunk-based inode with (optional) multi-device support:
101 * 5~7 - reserved
102 */
103enum {
104	EROFS_INODE_FLAT_PLAIN			= 0,
105	EROFS_INODE_COMPRESSED_FULL		= 1,
106	EROFS_INODE_FLAT_INLINE			= 2,
107	EROFS_INODE_COMPRESSED_COMPACT		= 3,
108	EROFS_INODE_CHUNK_BASED			= 4,
109	EROFS_INODE_DATALAYOUT_MAX
110};
111
112static inline bool erofs_inode_is_data_compressed(unsigned int datamode)
113{
114	return datamode == EROFS_INODE_COMPRESSED_COMPACT ||
115		datamode == EROFS_INODE_COMPRESSED_FULL;
116}
117
118/* bit definitions of inode i_format */
119#define EROFS_I_VERSION_MASK            0x01
120#define EROFS_I_DATALAYOUT_MASK         0x07
121
122#define EROFS_I_VERSION_BIT	0
123#define EROFS_I_DATALAYOUT_BIT	1
124#define EROFS_I_NLINK_1_BIT	4	/* non-directory compact inodes only */
125#define EROFS_I_DOT_OMITTED_BIT	4	/* (directories) omit the `.` dirent */
126#define EROFS_I_ALL		((1 << (EROFS_I_NLINK_1_BIT + 1)) - 1)
127
128/* indicate chunk blkbits, thus 'chunksize = blocksize << chunk blkbits' */
129#define EROFS_CHUNK_FORMAT_BLKBITS_MASK		0x001F
130/* with chunk indexes or just a 4-byte block array */
131#define EROFS_CHUNK_FORMAT_INDEXES		0x0020
132#define EROFS_CHUNK_FORMAT_48BIT		0x0040
133
134#define EROFS_CHUNK_FORMAT_ALL	((EROFS_CHUNK_FORMAT_48BIT << 1) - 1)
135
136/* 32-byte on-disk inode */
137#define EROFS_INODE_LAYOUT_COMPACT	0
138/* 64-byte on-disk inode */
139#define EROFS_INODE_LAYOUT_EXTENDED	1
140
141struct erofs_inode_chunk_info {
142	__le16 format;		/* chunk blkbits, etc. */
143	__le16 reserved;
144};
145
146union erofs_inode_i_u {
147	__le32 blocks_lo;	/* total blocks count (if compressed inodes) */
148	__le32 startblk_lo;	/* starting block number (if flat inodes) */
149	__le32 rdev;		/* device ID (if special inodes) */
150	struct erofs_inode_chunk_info c;
151};
152
153union erofs_inode_i_nb {
154	__le16 nlink;		/* if EROFS_I_NLINK_1_BIT is unset */
155	__le16 blocks_hi;	/* total blocks count MSB */
156	__le16 startblk_hi;	/* starting block number MSB */
157} __packed;
158
159/* 32-byte reduced form of an ondisk inode */
160struct erofs_inode_compact {
161	__le16 i_format;	/* inode format hints */
162	__le16 i_xattr_icount;
163	__le16 i_mode;
164	union erofs_inode_i_nb i_nb;
165	__le32 i_size;
166	__le32 i_mtime;
167	union erofs_inode_i_u i_u;
168
169	__le32 i_ino;		/* only used for 32-bit stat compatibility */
170	__le16 i_uid;
171	__le16 i_gid;
172	__le32 i_reserved;
173};
174
175/* 64-byte complete form of an ondisk inode */
176struct erofs_inode_extended {
177	__le16 i_format;	/* inode format hints */
178	__le16 i_xattr_icount;
179	__le16 i_mode;
180	union erofs_inode_i_nb i_nb;
181	__le64 i_size;
182	union erofs_inode_i_u i_u;
183
184	__le32 i_ino;		/* only used for 32-bit stat compatibility */
185	__le32 i_uid;
186	__le32 i_gid;
187	__le64 i_mtime;
188	__le32 i_mtime_nsec;
189	__le32 i_nlink;
190	__u8   i_reserved2[16];
191};
192
193/*
194 * inline xattrs (n == i_xattr_icount):
195 * erofs_xattr_ibody_header(1) + (n - 1) * 4 bytes
196 *          12 bytes           /                   \
197 *                            /                     \
198 *                           /-----------------------\
199 *                           |  erofs_xattr_entries+ |
200 *                           +-----------------------+
201 * inline xattrs must starts in erofs_xattr_ibody_header,
202 * for read-only fs, no need to introduce h_refcount
203 */
204struct erofs_xattr_ibody_header {
205	__le32 h_name_filter;		/* bit value 1 indicates not-present */
206	__u8   h_shared_count;
207	__u8   h_reserved2[7];
208	__le32 h_shared_xattrs[];       /* shared xattr id array */
209};
210
211/* Name indexes */
212#define EROFS_XATTR_INDEX_USER              1
213#define EROFS_XATTR_INDEX_POSIX_ACL_ACCESS  2
214#define EROFS_XATTR_INDEX_POSIX_ACL_DEFAULT 3
215#define EROFS_XATTR_INDEX_TRUSTED           4
216#define EROFS_XATTR_INDEX_LUSTRE            5
217#define EROFS_XATTR_INDEX_SECURITY          6
218
219/*
220 * bit 7 of e_name_index is set when it refers to a long xattr name prefix,
221 * while the remained lower bits represent the index of the prefix.
222 */
223#define EROFS_XATTR_LONG_PREFIX		0x80
224#define EROFS_XATTR_LONG_PREFIX_MASK	0x7f
225
226#define EROFS_XATTR_FILTER_BITS		32
227#define EROFS_XATTR_FILTER_DEFAULT	UINT32_MAX
228#define EROFS_XATTR_FILTER_SEED		0x25BBE08F
229
230/* xattr entry (for both inline & shared xattrs) */
231struct erofs_xattr_entry {
232	__u8   e_name_len;      /* length of name */
233	__u8   e_name_index;    /* attribute name index */
234	__le16 e_value_size;    /* size of attribute value */
235	/* followed by e_name and e_value */
236	char   e_name[];        /* attribute name */
237};
238
239/* long xattr name prefix */
240struct erofs_xattr_long_prefix {
241	__u8   base_index;	/* short xattr name prefix index */
242	char   infix[];		/* infix apart from short prefix */
243};
244
245static inline unsigned int erofs_xattr_ibody_size(__le16 i_xattr_icount)
246{
247	if (!i_xattr_icount)
248		return 0;
249
250	/* 1 header + n-1 * 4 bytes inline xattr to keep continuity */
251	return sizeof(struct erofs_xattr_ibody_header) +
252		sizeof(__u32) * (le16_to_cpu(i_xattr_icount) - 1);
253}
254
255#define EROFS_XATTR_ALIGN(size) round_up(size, sizeof(struct erofs_xattr_entry))
256
257static inline unsigned int erofs_xattr_entry_size(struct erofs_xattr_entry *e)
258{
259	return EROFS_XATTR_ALIGN(sizeof(struct erofs_xattr_entry) +
260				 e->e_name_len + le16_to_cpu(e->e_value_size));
261}
262
263/* represent a zeroed chunk (hole) */
264#define EROFS_NULL_ADDR			-1
265
266/* 4-byte block address array */
267#define EROFS_BLOCK_MAP_ENTRY_SIZE	sizeof(__le32)
268
269/* 8-byte inode chunk index */
270struct erofs_inode_chunk_index {
271	__le16 startblk_hi;	/* starting block number MSB */
272	__le16 device_id;	/* back-end storage id (with bits masked) */
273	__le32 startblk_lo;	/* starting block number of this chunk */
274};
275
276#define EROFS_DIRENT_NID_METABOX_BIT	63
277#define EROFS_DIRENT_NID_MASK	(BIT_ULL(EROFS_DIRENT_NID_METABOX_BIT) - 1)
278
279/* dirent sorts in alphabet order, thus we can do binary search */
280struct erofs_dirent {
281	__le64 nid;     /* node number */
282	__le16 nameoff; /* start offset of file name */
283	__u8 file_type; /* file type */
284	__u8 reserved;  /* reserved */
285} __packed;
286
287/*
288 * EROFS file types should match generic FT_* types and
289 * it seems no need to add BUILD_BUG_ONs since potential
290 * unmatchness will break other fses as well...
291 */
292
293#define EROFS_NAME_LEN      255
294
295/* maximum supported encoded size of a physical compressed cluster */
296#define Z_EROFS_PCLUSTER_MAX_SIZE	(1024 * 1024)
297
298/* maximum supported decoded size of a physical compressed cluster */
299#define Z_EROFS_PCLUSTER_MAX_DSIZE	(12 * 1024 * 1024)
300
301/* available compression algorithm types (for h_algorithmtype) */
302enum {
303	Z_EROFS_COMPRESSION_LZ4		= 0,
304	Z_EROFS_COMPRESSION_LZMA	= 1,
305	Z_EROFS_COMPRESSION_DEFLATE	= 2,
306	Z_EROFS_COMPRESSION_ZSTD	= 3,
307	Z_EROFS_COMPRESSION_MAX
308};
309#define Z_EROFS_ALL_COMPR_ALGS		((1 << Z_EROFS_COMPRESSION_MAX) - 1)
310
311/* 14 bytes (+ length field = 16 bytes) */
312struct z_erofs_lz4_cfgs {
313	__le16 max_distance;
314	__le16 max_pclusterblks;
315	u8 reserved[10];
316} __packed;
317
318/* 14 bytes (+ length field = 16 bytes) */
319struct z_erofs_lzma_cfgs {
320	__le32 dict_size;
321	__le16 format;
322	u8 reserved[8];
323} __packed;
324
325#define Z_EROFS_LZMA_MAX_DICT_SIZE	(8 * Z_EROFS_PCLUSTER_MAX_SIZE)
326
327/* 6 bytes (+ length field = 8 bytes) */
328struct z_erofs_deflate_cfgs {
329	u8 windowbits;			/* 8..15 for DEFLATE */
330	u8 reserved[5];
331} __packed;
332
333/* 6 bytes (+ length field = 8 bytes) */
334struct z_erofs_zstd_cfgs {
335	u8 format;
336	u8 windowlog;           /* windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN(10) */
337	u8 reserved[4];
338} __packed;
339
340#define Z_EROFS_ZSTD_MAX_DICT_SIZE      Z_EROFS_PCLUSTER_MAX_SIZE
341
342/*
343 * Enable COMPACTED_2B for EROFS_INODE_COMPRESSED_COMPACT inodes:
344 *   4B (disabled) vs 4B+2B+4B (enabled)
345 */
346#define Z_EROFS_ADVISE_COMPACTED_2B		0x0001
347/* Enable extent metadata for EROFS_INODE_COMPRESSED_FULL inodes */
348#define Z_EROFS_ADVISE_EXTENTS			0x0001
349#define Z_EROFS_ADVISE_BIG_PCLUSTER_1		0x0002
350#define Z_EROFS_ADVISE_BIG_PCLUSTER_2		0x0004
351#define Z_EROFS_ADVISE_INLINE_PCLUSTER		0x0008
352#define Z_EROFS_ADVISE_INTERLACED_PCLUSTER	0x0010
353#define Z_EROFS_ADVISE_FRAGMENT_PCLUSTER	0x0020
354/* Indicate the record size for each extent if extent metadata is used */
355#define Z_EROFS_ADVISE_EXTRECSZ_BIT		1
356#define Z_EROFS_ADVISE_EXTRECSZ_MASK		0x3
357
358#define Z_EROFS_FRAGMENT_INODE_BIT              7
359struct z_erofs_map_header {
360	union {
361		/* fragment data offset in the packed inode */
362		__le32  h_fragmentoff;
363		struct {
364			__le16  h_reserved1;
365			/* indicates the encoded size of tailpacking data */
366			__le16  h_idata_size;
367		};
368		__le32 h_extents_lo;	/* extent count LSB */
369	};
370	__le16	h_advise;
371	union {
372		struct {
373			/* algorithm type (bit 0-3: HEAD1; bit 4-7: HEAD2) */
374			__u8	h_algorithmtype;
375			/*
376			 * bit 0-3 : logical cluster bits - blkszbits
377			 * bit 4-6 : reserved
378			 * bit 7   : pack the whole file into packed inode
379			 */
380			__u8	h_clusterbits;
381		} __packed;
382		__le16 h_extents_hi;	/* extent count MSB */
383	} __packed;
384};
385
386enum {
387	Z_EROFS_LCLUSTER_TYPE_PLAIN	= 0,
388	Z_EROFS_LCLUSTER_TYPE_HEAD1	= 1,
389	Z_EROFS_LCLUSTER_TYPE_NONHEAD	= 2,
390	Z_EROFS_LCLUSTER_TYPE_HEAD2	= 3,
391	Z_EROFS_LCLUSTER_TYPE_MAX
392};
393
394#define Z_EROFS_LI_LCLUSTER_TYPE_MASK	(Z_EROFS_LCLUSTER_TYPE_MAX - 1)
395
396/* (noncompact only, HEAD) This pcluster refers to partial decompressed data */
397#define Z_EROFS_LI_PARTIAL_REF		(1 << 15)
398
399/* Set on 1st non-head lcluster to store compressed block counti (in blocks) */
400#define Z_EROFS_LI_D0_CBLKCNT		(1 << 11)
401
402struct z_erofs_lcluster_index {
403	__le16 di_advise;
404	/* where to decompress in the head lcluster */
405	__le16 di_clusterofs;
406
407	union {
408		__le32 blkaddr;		/* for the HEAD lclusters */
409		/*
410		 * [0] - distance to its HEAD lcluster
411		 * [1] - distance to the next HEAD lcluster
412		 */
413		__le16 delta[2];	/* for the NONHEAD lclusters */
414	} di_u;
415};
416
417#define Z_EROFS_MAP_HEADER_END(end)	\
418	(ALIGN(end, 8) + sizeof(struct z_erofs_map_header))
419#define Z_EROFS_FULL_INDEX_START(end)	(Z_EROFS_MAP_HEADER_END(end) + 8)
420
421#define Z_EROFS_EXTENT_PLEN_PARTIAL	BIT(27)
422#define Z_EROFS_EXTENT_PLEN_FMT_BIT	28
423#define Z_EROFS_EXTENT_PLEN_MASK	((Z_EROFS_PCLUSTER_MAX_SIZE << 1) - 1)
424struct z_erofs_extent {
425	__le32 plen;		/* encoded length */
426	__le32 pstart_lo;	/* physical offset */
427	__le32 pstart_hi;	/* physical offset MSB */
428	__le32 lstart_lo;	/* logical offset */
429	__le32 lstart_hi;	/* logical offset MSB (>= 4GiB inodes) */
430	__u8 reserved[12];	/* for future use */
431};
432
433static inline int z_erofs_extent_recsize(unsigned int advise)
434{
435	return 4 << ((advise >> Z_EROFS_ADVISE_EXTRECSZ_BIT) &
436		Z_EROFS_ADVISE_EXTRECSZ_MASK);
437}
438
439/* check the EROFS on-disk layout strictly at compile time */
440static inline void erofs_check_ondisk_layout_definitions(void)
441{
442	const __le64 fmh = *(__le64 *)&(struct z_erofs_map_header) {
443		.h_clusterbits = 1 << Z_EROFS_FRAGMENT_INODE_BIT
444	};
445
446	BUILD_BUG_ON(sizeof(struct erofs_super_block) != 144);
447	BUILD_BUG_ON(sizeof(struct erofs_inode_compact) != 32);
448	BUILD_BUG_ON(sizeof(struct erofs_inode_extended) != 64);
449	BUILD_BUG_ON(sizeof(struct erofs_xattr_ibody_header) != 12);
450	BUILD_BUG_ON(sizeof(struct erofs_xattr_entry) != 4);
451	BUILD_BUG_ON(sizeof(struct erofs_inode_chunk_info) != 4);
452	BUILD_BUG_ON(sizeof(struct erofs_inode_chunk_index) != 8);
453	BUILD_BUG_ON(sizeof(struct z_erofs_map_header) != 8);
454	BUILD_BUG_ON(sizeof(struct z_erofs_lcluster_index) != 8);
455	BUILD_BUG_ON(sizeof(struct erofs_dirent) != 12);
456	/* keep in sync between 2 index structures for better extendibility */
457	BUILD_BUG_ON(sizeof(struct erofs_inode_chunk_index) !=
458		     sizeof(struct z_erofs_lcluster_index));
459	BUILD_BUG_ON(sizeof(struct erofs_deviceslot) != 128);
460
461	/* exclude old compiler versions like gcc 7.5.0 */
462	BUILD_BUG_ON(__builtin_constant_p(fmh) ?
463		     fmh != cpu_to_le64(1ULL << 63) : 0);
464}
465
466#endif
~/ Read-only file preview.