]>
Commit | Line | Data |
---|---|---|
29b24f6c GX |
1 | /* SPDX-License-Identifier: GPL-2.0-only OR Apache-2.0 */ |
2 | /* | |
ea559e7b GX |
3 | * EROFS (Enhanced ROM File System) on-disk format definition |
4 | * | |
aea1286d | 5 | * Copyright (C) 2017-2018 HUAWEI, Inc. |
592e7cd0 | 6 | * https://www.huawei.com/ |
2a9dc7a8 | 7 | * Copyright (C) 2021, Alibaba Cloud |
aea1286d GX |
8 | */ |
9 | #ifndef __EROFS_FS_H | |
10 | #define __EROFS_FS_H | |
11 | ||
aea1286d GX |
12 | #define EROFS_SUPER_OFFSET 1024 |
13 | ||
b858a484 | 14 | #define EROFS_FEATURE_COMPAT_SB_CHKSUM 0x00000001 |
a1108dcd | 15 | #define EROFS_FEATURE_COMPAT_MTIME 0x00000002 |
b858a484 | 16 | |
5efe5137 | 17 | /* |
426a9308 GX |
18 | * Any bits that aren't in EROFS_ALL_FEATURE_INCOMPAT should |
19 | * be incompatible with this kernel version. | |
5efe5137 | 20 | */ |
7e508f2c | 21 | #define EROFS_FEATURE_INCOMPAT_ZERO_PADDING 0x00000001 |
14373711 | 22 | #define EROFS_FEATURE_INCOMPAT_COMPR_CFGS 0x00000002 |
5404c330 | 23 | #define EROFS_FEATURE_INCOMPAT_BIG_PCLUSTER 0x00000002 |
2a9dc7a8 | 24 | #define EROFS_FEATURE_INCOMPAT_CHUNKED_FILE 0x00000004 |
dfeab2e9 | 25 | #define EROFS_FEATURE_INCOMPAT_DEVICE_TABLE 0x00000008 |
72bb5262 | 26 | #define EROFS_FEATURE_INCOMPAT_COMPR_HEAD2 0x00000008 |
ab92184f | 27 | #define EROFS_FEATURE_INCOMPAT_ZTAILPACKING 0x00000010 |
b15b2e30 | 28 | #define EROFS_FEATURE_INCOMPAT_FRAGMENTS 0x00000020 |
5c2a6425 | 29 | #define EROFS_FEATURE_INCOMPAT_DEDUPE 0x00000020 |
8e6c8fa9 | 30 | #define EROFS_ALL_FEATURE_INCOMPAT \ |
7e508f2c | 31 | (EROFS_FEATURE_INCOMPAT_ZERO_PADDING | \ |
8e6c8fa9 | 32 | EROFS_FEATURE_INCOMPAT_COMPR_CFGS | \ |
2a9dc7a8 | 33 | EROFS_FEATURE_INCOMPAT_BIG_PCLUSTER | \ |
dfeab2e9 | 34 | EROFS_FEATURE_INCOMPAT_CHUNKED_FILE | \ |
72bb5262 | 35 | EROFS_FEATURE_INCOMPAT_DEVICE_TABLE | \ |
ab92184f | 36 | EROFS_FEATURE_INCOMPAT_COMPR_HEAD2 | \ |
b15b2e30 | 37 | EROFS_FEATURE_INCOMPAT_ZTAILPACKING | \ |
5c2a6425 GX |
38 | EROFS_FEATURE_INCOMPAT_FRAGMENTS | \ |
39 | EROFS_FEATURE_INCOMPAT_DEDUPE) | |
5efe5137 | 40 | |
14373711 GX |
41 | #define EROFS_SB_EXTSLOT_SIZE 16 |
42 | ||
dfeab2e9 | 43 | struct erofs_deviceslot { |
ba73eadd JX |
44 | u8 tag[64]; /* digest(sha256), etc. */ |
45 | __le32 blocks; /* total fs blocks of this device */ | |
46 | __le32 mapped_blkaddr; /* map starting at mapped_blkaddr */ | |
dfeab2e9 GX |
47 | u8 reserved[56]; |
48 | }; | |
49 | #define EROFS_DEVT_SLOT_SIZE sizeof(struct erofs_deviceslot) | |
50 | ||
14373711 | 51 | /* erofs on-disk super block (currently 128 bytes) */ |
aea1286d | 52 | struct erofs_super_block { |
4b66eb51 GX |
53 | __le32 magic; /* file system magic number */ |
54 | __le32 checksum; /* crc32c(super_block) */ | |
426a9308 | 55 | __le32 feature_compat; |
4b66eb51 | 56 | __u8 blkszbits; /* support block_size == PAGE_SIZE only */ |
14373711 | 57 | __u8 sb_extslots; /* superblock size = 128 + sb_extslots * 16 */ |
4b66eb51 GX |
58 | |
59 | __le16 root_nid; /* nid of root directory */ | |
60 | __le64 inos; /* total valid ino # (== f_files - f_favail) */ | |
61 | ||
2833f4bb GX |
62 | __le64 build_time; /* compact inode time derivation */ |
63 | __le32 build_time_nsec; /* compact inode time derivation in ns scale */ | |
4b66eb51 GX |
64 | __le32 blocks; /* used for statfs */ |
65 | __le32 meta_blkaddr; /* start block address of metadata area */ | |
66 | __le32 xattr_blkaddr; /* start block address of shared xattr area */ | |
67 | __u8 uuid[16]; /* 128-bit uuid for volume */ | |
68 | __u8 volume_name[16]; /* volume name */ | |
426a9308 | 69 | __le32 feature_incompat; |
14373711 GX |
70 | union { |
71 | /* bitmap for available compression algorithms */ | |
72 | __le16 available_compr_algs; | |
73 | /* customized sliding window size instead of 64k by default */ | |
74 | __le16 lz4_max_distance; | |
75 | } __packed u1; | |
dfeab2e9 GX |
76 | __le16 extra_devices; /* # of devices besides the primary device */ |
77 | __le16 devt_slotoff; /* startoff = devt_slotoff * devt_slotsize */ | |
b15b2e30 YH |
78 | __u8 reserved[6]; |
79 | __le64 packed_nid; /* nid of the special packed inode */ | |
80 | __u8 reserved2[24]; | |
ed34aa4a | 81 | }; |
aea1286d | 82 | |
aea1286d | 83 | /* |
ea559e7b | 84 | * erofs inode datalayout (i_format in on-disk inode): |
2833f4bb | 85 | * 0 - uncompressed flat inode without tail-packing inline data: |
aea1286d | 86 | * inode, [xattrs], ... | ... | no-holed data |
2833f4bb GX |
87 | * 1 - compressed inode with non-compact indexes: |
88 | * inode, [xattrs], [map_header], extents ... | ... | |
89 | * 2 - uncompressed flat inode with tail-packing inline data: | |
90 | * inode, [xattrs], tailpacking data, ... | ... | no-holed data | |
91 | * 3 - compressed inode with compact indexes: | |
ec8c2442 | 92 | * inode, [xattrs], map_header, extents ... | ... |
2833f4bb | 93 | * 4 - chunk-based inode with (optional) multi-device support: |
2a9dc7a8 GX |
94 | * inode, [xattrs], chunk indexes ... | ... |
95 | * 5~7 - reserved | |
aea1286d GX |
96 | */ |
97 | enum { | |
60a49ba8 GX |
98 | EROFS_INODE_FLAT_PLAIN = 0, |
99 | EROFS_INODE_FLAT_COMPRESSION_LEGACY = 1, | |
100 | EROFS_INODE_FLAT_INLINE = 2, | |
101 | EROFS_INODE_FLAT_COMPRESSION = 3, | |
2a9dc7a8 | 102 | EROFS_INODE_CHUNK_BASED = 4, |
8a765682 | 103 | EROFS_INODE_DATALAYOUT_MAX |
aea1286d | 104 | }; |
ccd9c19c | 105 | |
3d2969fa | 106 | static inline bool erofs_inode_is_data_compressed(unsigned int datamode) |
ec8c2442 | 107 | { |
c39747f7 GX |
108 | return datamode == EROFS_INODE_FLAT_COMPRESSION || |
109 | datamode == EROFS_INODE_FLAT_COMPRESSION_LEGACY; | |
ec8c2442 GX |
110 | } |
111 | ||
2833f4bb | 112 | /* bit definitions of inode i_format */ |
aea1286d | 113 | #define EROFS_I_VERSION_BITS 1 |
8a765682 | 114 | #define EROFS_I_DATALAYOUT_BITS 3 |
aea1286d GX |
115 | |
116 | #define EROFS_I_VERSION_BIT 0 | |
8a765682 | 117 | #define EROFS_I_DATALAYOUT_BIT 1 |
aea1286d | 118 | |
24a806d8 GX |
119 | #define EROFS_I_ALL \ |
120 | ((1 << (EROFS_I_DATALAYOUT_BIT + EROFS_I_DATALAYOUT_BITS)) - 1) | |
121 | ||
2a9dc7a8 GX |
122 | /* indicate chunk blkbits, thus 'chunksize = blocksize << chunk blkbits' */ |
123 | #define EROFS_CHUNK_FORMAT_BLKBITS_MASK 0x001F | |
124 | /* with chunk indexes or just a 4-byte blkaddr array */ | |
125 | #define EROFS_CHUNK_FORMAT_INDEXES 0x0020 | |
126 | ||
127 | #define EROFS_CHUNK_FORMAT_ALL \ | |
128 | (EROFS_CHUNK_FORMAT_BLKBITS_MASK | EROFS_CHUNK_FORMAT_INDEXES) | |
129 | ||
130 | struct erofs_inode_chunk_info { | |
131 | __le16 format; /* chunk blkbits, etc. */ | |
132 | __le16 reserved; | |
133 | }; | |
134 | ||
4b66eb51 | 135 | /* 32-byte reduced form of an ondisk inode */ |
8a765682 GX |
136 | struct erofs_inode_compact { |
137 | __le16 i_format; /* inode format hints */ | |
aea1286d GX |
138 | |
139 | /* 1 header + n-1 * 4 bytes inline xattr to keep continuity */ | |
4b66eb51 GX |
140 | __le16 i_xattr_icount; |
141 | __le16 i_mode; | |
142 | __le16 i_nlink; | |
143 | __le32 i_size; | |
144 | __le32 i_reserved; | |
145 | union { | |
2833f4bb | 146 | /* total compressed blocks for compressed inodes */ |
aea1286d | 147 | __le32 compressed_blocks; |
2833f4bb | 148 | /* block address for uncompressed flat inodes */ |
aea1286d GX |
149 | __le32 raw_blkaddr; |
150 | ||
151 | /* for device files, used to indicate old/new device # */ | |
152 | __le32 rdev; | |
2a9dc7a8 GX |
153 | |
154 | /* for chunk-based files, it contains the summary info */ | |
155 | struct erofs_inode_chunk_info c; | |
ed34aa4a | 156 | } i_u; |
4b66eb51 GX |
157 | __le32 i_ino; /* only used for 32-bit stat compatibility */ |
158 | __le16 i_uid; | |
159 | __le16 i_gid; | |
160 | __le32 i_reserved2; | |
ed34aa4a | 161 | }; |
aea1286d | 162 | |
2833f4bb | 163 | /* 32-byte on-disk inode */ |
8a765682 | 164 | #define EROFS_INODE_LAYOUT_COMPACT 0 |
2833f4bb | 165 | /* 64-byte on-disk inode */ |
8a765682 | 166 | #define EROFS_INODE_LAYOUT_EXTENDED 1 |
aea1286d | 167 | |
4b66eb51 | 168 | /* 64-byte complete form of an ondisk inode */ |
8a765682 GX |
169 | struct erofs_inode_extended { |
170 | __le16 i_format; /* inode format hints */ | |
cead56f8 GX |
171 | |
172 | /* 1 header + n-1 * 4 bytes inline xattr to keep continuity */ | |
4b66eb51 GX |
173 | __le16 i_xattr_icount; |
174 | __le16 i_mode; | |
175 | __le16 i_reserved; | |
176 | __le64 i_size; | |
177 | union { | |
2833f4bb | 178 | /* total compressed blocks for compressed inodes */ |
aea1286d | 179 | __le32 compressed_blocks; |
2833f4bb | 180 | /* block address for uncompressed flat inodes */ |
aea1286d GX |
181 | __le32 raw_blkaddr; |
182 | ||
183 | /* for device files, used to indicate old/new device # */ | |
184 | __le32 rdev; | |
2a9dc7a8 GX |
185 | |
186 | /* for chunk-based files, it contains the summary info */ | |
187 | struct erofs_inode_chunk_info c; | |
ed34aa4a | 188 | } i_u; |
aea1286d GX |
189 | |
190 | /* only used for 32-bit stat compatibility */ | |
4b66eb51 GX |
191 | __le32 i_ino; |
192 | ||
193 | __le32 i_uid; | |
194 | __le32 i_gid; | |
a1108dcd DA |
195 | __le64 i_mtime; |
196 | __le32 i_mtime_nsec; | |
4b66eb51 GX |
197 | __le32 i_nlink; |
198 | __u8 i_reserved2[16]; | |
ed34aa4a | 199 | }; |
aea1286d GX |
200 | |
201 | #define EROFS_MAX_SHARED_XATTRS (128) | |
202 | /* h_shared_count between 129 ... 255 are special # */ | |
203 | #define EROFS_SHARED_XATTR_EXTENT (255) | |
204 | ||
205 | /* | |
206 | * inline xattrs (n == i_xattr_icount): | |
207 | * erofs_xattr_ibody_header(1) + (n - 1) * 4 bytes | |
208 | * 12 bytes / \ | |
209 | * / \ | |
210 | * /-----------------------\ | |
211 | * | erofs_xattr_entries+ | | |
212 | * +-----------------------+ | |
213 | * inline xattrs must starts in erofs_xattr_ibody_header, | |
214 | * for read-only fs, no need to introduce h_refcount | |
215 | */ | |
216 | struct erofs_xattr_ibody_header { | |
cead56f8 | 217 | __le32 h_reserved; |
aea1286d | 218 | __u8 h_shared_count; |
cead56f8 | 219 | __u8 h_reserved2[7]; |
7acc3d1a | 220 | __le32 h_shared_xattrs[]; /* shared xattr id array */ |
ed34aa4a | 221 | }; |
aea1286d GX |
222 | |
223 | /* Name indexes */ | |
224 | #define EROFS_XATTR_INDEX_USER 1 | |
225 | #define EROFS_XATTR_INDEX_POSIX_ACL_ACCESS 2 | |
226 | #define EROFS_XATTR_INDEX_POSIX_ACL_DEFAULT 3 | |
227 | #define EROFS_XATTR_INDEX_TRUSTED 4 | |
228 | #define EROFS_XATTR_INDEX_LUSTRE 5 | |
229 | #define EROFS_XATTR_INDEX_SECURITY 6 | |
230 | ||
231 | /* xattr entry (for both inline & shared xattrs) */ | |
232 | struct erofs_xattr_entry { | |
233 | __u8 e_name_len; /* length of name */ | |
234 | __u8 e_name_index; /* attribute name index */ | |
235 | __le16 e_value_size; /* size of attribute value */ | |
236 | /* followed by e_name and e_value */ | |
7acc3d1a | 237 | char e_name[]; /* attribute name */ |
ed34aa4a | 238 | }; |
aea1286d | 239 | |
b6796abd GX |
240 | static inline unsigned int erofs_xattr_ibody_size(__le16 i_xattr_icount) |
241 | { | |
242 | if (!i_xattr_icount) | |
243 | return 0; | |
244 | ||
245 | return sizeof(struct erofs_xattr_ibody_header) + | |
246 | sizeof(__u32) * (le16_to_cpu(i_xattr_icount) - 1); | |
247 | } | |
aea1286d GX |
248 | |
249 | #define EROFS_XATTR_ALIGN(size) round_up(size, sizeof(struct erofs_xattr_entry)) | |
b6796abd GX |
250 | |
251 | static inline unsigned int erofs_xattr_entry_size(struct erofs_xattr_entry *e) | |
252 | { | |
253 | return EROFS_XATTR_ALIGN(sizeof(struct erofs_xattr_entry) + | |
254 | e->e_name_len + le16_to_cpu(e->e_value_size)); | |
255 | } | |
aea1286d | 256 | |
2a9dc7a8 GX |
257 | /* represent a zeroed chunk (hole) */ |
258 | #define EROFS_NULL_ADDR -1 | |
259 | ||
260 | /* 4-byte block address array */ | |
261 | #define EROFS_BLOCK_MAP_ENTRY_SIZE sizeof(__le32) | |
262 | ||
263 | /* 8-byte inode chunk indexes */ | |
264 | struct erofs_inode_chunk_index { | |
265 | __le16 advise; /* always 0, don't care for now */ | |
dfeab2e9 | 266 | __le16 device_id; /* back-end storage id (with bits masked) */ |
2a9dc7a8 GX |
267 | __le32 blkaddr; /* start block address of this inode chunk */ |
268 | }; | |
269 | ||
9f6cc76e GX |
270 | /* maximum supported size of a physical compression cluster */ |
271 | #define Z_EROFS_PCLUSTER_MAX_SIZE (1024 * 1024) | |
272 | ||
ea559e7b | 273 | /* available compression algorithm types (for h_algorithmtype) */ |
ec8c2442 | 274 | enum { |
622ceadd GX |
275 | Z_EROFS_COMPRESSION_LZ4 = 0, |
276 | Z_EROFS_COMPRESSION_LZMA = 1, | |
ec8c2442 GX |
277 | Z_EROFS_COMPRESSION_MAX |
278 | }; | |
622ceadd | 279 | #define Z_EROFS_ALL_COMPR_ALGS ((1 << Z_EROFS_COMPRESSION_MAX) - 1) |
ec8c2442 | 280 | |
46249cde GX |
281 | /* 14 bytes (+ length field = 16 bytes) */ |
282 | struct z_erofs_lz4_cfgs { | |
283 | __le16 max_distance; | |
5404c330 GX |
284 | __le16 max_pclusterblks; |
285 | u8 reserved[10]; | |
46249cde GX |
286 | } __packed; |
287 | ||
622ceadd GX |
288 | /* 14 bytes (+ length field = 16 bytes) */ |
289 | struct z_erofs_lzma_cfgs { | |
290 | __le32 dict_size; | |
291 | __le16 format; | |
292 | u8 reserved[8]; | |
293 | } __packed; | |
294 | ||
295 | #define Z_EROFS_LZMA_MAX_DICT_SIZE (8 * Z_EROFS_PCLUSTER_MAX_SIZE) | |
296 | ||
ec8c2442 GX |
297 | /* |
298 | * bit 0 : COMPACTED_2B indexes (0 - off; 1 - on) | |
299 | * e.g. for 4k logical cluster size, 4B if compacted 2B is off; | |
300 | * (4B) + 2B + (4B) if compacted 2B is on. | |
5404c330 GX |
301 | * bit 1 : HEAD1 big pcluster (0 - off; 1 - on) |
302 | * bit 2 : HEAD2 big pcluster (0 - off; 1 - on) | |
ab92184f | 303 | * bit 3 : tailpacking inline pcluster (0 - off; 1 - on) |
fdffc091 | 304 | * bit 4 : interlaced plain pcluster (0 - off; 1 - on) |
b15b2e30 | 305 | * bit 5 : fragment pcluster (0 - off; 1 - on) |
ec8c2442 | 306 | */ |
5404c330 GX |
307 | #define Z_EROFS_ADVISE_COMPACTED_2B 0x0001 |
308 | #define Z_EROFS_ADVISE_BIG_PCLUSTER_1 0x0002 | |
309 | #define Z_EROFS_ADVISE_BIG_PCLUSTER_2 0x0004 | |
ab92184f | 310 | #define Z_EROFS_ADVISE_INLINE_PCLUSTER 0x0008 |
fdffc091 | 311 | #define Z_EROFS_ADVISE_INTERLACED_PCLUSTER 0x0010 |
b15b2e30 | 312 | #define Z_EROFS_ADVISE_FRAGMENT_PCLUSTER 0x0020 |
ec8c2442 | 313 | |
b15b2e30 | 314 | #define Z_EROFS_FRAGMENT_INODE_BIT 7 |
ec8c2442 | 315 | struct z_erofs_map_header { |
b15b2e30 YH |
316 | union { |
317 | /* fragment data offset in the packed inode */ | |
318 | __le32 h_fragmentoff; | |
319 | struct { | |
320 | __le16 h_reserved1; | |
321 | /* indicates the encoded size of tailpacking data */ | |
322 | __le16 h_idata_size; | |
323 | }; | |
324 | }; | |
ec8c2442 GX |
325 | __le16 h_advise; |
326 | /* | |
327 | * bit 0-3 : algorithm type of head 1 (logical cluster type 01); | |
328 | * bit 4-7 : algorithm type of head 2 (logical cluster type 11). | |
329 | */ | |
330 | __u8 h_algorithmtype; | |
331 | /* | |
332 | * bit 0-2 : logical cluster bits - 12, e.g. 0 for 4096; | |
b15b2e30 YH |
333 | * bit 3-6 : reserved; |
334 | * bit 7 : move the whole file into packed inode or not. | |
ec8c2442 GX |
335 | */ |
336 | __u8 h_clusterbits; | |
337 | }; | |
338 | ||
339 | #define Z_EROFS_VLE_LEGACY_HEADER_PADDING 8 | |
aea1286d GX |
340 | |
341 | /* | |
72bb5262 GX |
342 | * Fixed-sized output compression on-disk logical cluster type: |
343 | * 0 - literal (uncompressed) lcluster | |
344 | * 1,3 - compressed lcluster (for HEAD lclusters) | |
345 | * 2 - compressed lcluster (for NONHEAD lclusters) | |
aea1286d GX |
346 | * |
347 | * In detail, | |
72bb5262 | 348 | * 0 - literal (uncompressed) lcluster, |
aea1286d | 349 | * di_advise = 0 |
72bb5262 GX |
350 | * di_clusterofs = the literal data offset of the lcluster |
351 | * di_blkaddr = the blkaddr of the literal pcluster | |
aea1286d | 352 | * |
72bb5262 GX |
353 | * 1,3 - compressed lcluster (for HEAD lclusters) |
354 | * di_advise = 1 or 3 | |
355 | * di_clusterofs = the decompressed data offset of the lcluster | |
356 | * di_blkaddr = the blkaddr of the compressed pcluster | |
aea1286d | 357 | * |
72bb5262 | 358 | * 2 - compressed lcluster (for NONHEAD lclusters) |
aea1286d GX |
359 | * di_advise = 2 |
360 | * di_clusterofs = | |
72bb5262 GX |
361 | * the decompressed data offset in its own HEAD lcluster |
362 | * di_u.delta[0] = distance to this HEAD lcluster | |
363 | * di_u.delta[1] = distance to the next HEAD lcluster | |
aea1286d | 364 | */ |
99691b46 | 365 | enum { |
60a49ba8 | 366 | Z_EROFS_VLE_CLUSTER_TYPE_PLAIN = 0, |
72bb5262 | 367 | Z_EROFS_VLE_CLUSTER_TYPE_HEAD1 = 1, |
60a49ba8 | 368 | Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD = 2, |
72bb5262 | 369 | Z_EROFS_VLE_CLUSTER_TYPE_HEAD2 = 3, |
99691b46 GX |
370 | Z_EROFS_VLE_CLUSTER_TYPE_MAX |
371 | }; | |
372 | ||
aea1286d GX |
373 | #define Z_EROFS_VLE_DI_CLUSTER_TYPE_BITS 2 |
374 | #define Z_EROFS_VLE_DI_CLUSTER_TYPE_BIT 0 | |
375 | ||
5c2a6425 GX |
376 | /* (noncompact only, HEAD) This pcluster refers to partial decompressed data */ |
377 | #define Z_EROFS_VLE_DI_PARTIAL_REF (1 << 15) | |
378 | ||
5404c330 GX |
379 | /* |
380 | * D0_CBLKCNT will be marked _only_ at the 1st non-head lcluster to store the | |
381 | * compressed block count of a compressed extent (in logical clusters, aka. | |
382 | * block count of a pcluster). | |
383 | */ | |
384 | #define Z_EROFS_VLE_DI_D0_CBLKCNT (1 << 11) | |
385 | ||
aea1286d GX |
386 | struct z_erofs_vle_decompressed_index { |
387 | __le16 di_advise; | |
2833f4bb | 388 | /* where to decompress in the head lcluster */ |
aea1286d GX |
389 | __le16 di_clusterofs; |
390 | ||
391 | union { | |
2833f4bb | 392 | /* for the HEAD lclusters */ |
aea1286d GX |
393 | __le32 blkaddr; |
394 | /* | |
2833f4bb GX |
395 | * for the NONHEAD lclusters |
396 | * [0] - distance to its HEAD lcluster | |
397 | * [1] - distance to the next HEAD lcluster | |
aea1286d GX |
398 | */ |
399 | __le16 delta[2]; | |
ed34aa4a GX |
400 | } di_u; |
401 | }; | |
aea1286d | 402 | |
ec8c2442 GX |
403 | #define Z_EROFS_VLE_LEGACY_INDEX_ALIGN(size) \ |
404 | (round_up(size, sizeof(struct z_erofs_vle_decompressed_index)) + \ | |
405 | sizeof(struct z_erofs_map_header) + Z_EROFS_VLE_LEGACY_HEADER_PADDING) | |
aea1286d GX |
406 | |
407 | /* dirent sorts in alphabet order, thus we can do binary search */ | |
408 | struct erofs_dirent { | |
4b66eb51 GX |
409 | __le64 nid; /* node number */ |
410 | __le16 nameoff; /* start offset of file name */ | |
411 | __u8 file_type; /* file type */ | |
412 | __u8 reserved; /* reserved */ | |
aea1286d GX |
413 | } __packed; |
414 | ||
1d819c54 GX |
415 | /* |
416 | * EROFS file types should match generic FT_* types and | |
417 | * it seems no need to add BUILD_BUG_ONs since potential | |
418 | * unmatchness will break other fses as well... | |
419 | */ | |
aea1286d GX |
420 | |
421 | #define EROFS_NAME_LEN 255 | |
422 | ||
423 | /* check the EROFS on-disk layout strictly at compile time */ | |
424 | static inline void erofs_check_ondisk_layout_definitions(void) | |
425 | { | |
b15b2e30 YH |
426 | const __le64 fmh = *(__le64 *)&(struct z_erofs_map_header) { |
427 | .h_clusterbits = 1 << Z_EROFS_FRAGMENT_INODE_BIT | |
428 | }; | |
429 | ||
aea1286d | 430 | BUILD_BUG_ON(sizeof(struct erofs_super_block) != 128); |
8a765682 GX |
431 | BUILD_BUG_ON(sizeof(struct erofs_inode_compact) != 32); |
432 | BUILD_BUG_ON(sizeof(struct erofs_inode_extended) != 64); | |
aea1286d GX |
433 | BUILD_BUG_ON(sizeof(struct erofs_xattr_ibody_header) != 12); |
434 | BUILD_BUG_ON(sizeof(struct erofs_xattr_entry) != 4); | |
2a9dc7a8 GX |
435 | BUILD_BUG_ON(sizeof(struct erofs_inode_chunk_info) != 4); |
436 | BUILD_BUG_ON(sizeof(struct erofs_inode_chunk_index) != 8); | |
ec8c2442 | 437 | BUILD_BUG_ON(sizeof(struct z_erofs_map_header) != 8); |
aea1286d GX |
438 | BUILD_BUG_ON(sizeof(struct z_erofs_vle_decompressed_index) != 8); |
439 | BUILD_BUG_ON(sizeof(struct erofs_dirent) != 12); | |
2a9dc7a8 GX |
440 | /* keep in sync between 2 index structures for better extendibility */ |
441 | BUILD_BUG_ON(sizeof(struct erofs_inode_chunk_index) != | |
442 | sizeof(struct z_erofs_vle_decompressed_index)); | |
dfeab2e9 | 443 | BUILD_BUG_ON(sizeof(struct erofs_deviceslot) != 128); |
99691b46 GX |
444 | |
445 | BUILD_BUG_ON(BIT(Z_EROFS_VLE_DI_CLUSTER_TYPE_BITS) < | |
446 | Z_EROFS_VLE_CLUSTER_TYPE_MAX - 1); | |
b15b2e30 YH |
447 | /* exclude old compiler versions like gcc 7.5.0 */ |
448 | BUILD_BUG_ON(__builtin_constant_p(fmh) ? | |
449 | fmh != cpu_to_le64(1ULL << 63) : 0); | |
aea1286d GX |
450 | } |
451 | ||
452 | #endif |