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