2 * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
6 * Copyright (c) 2012 Martin Sucha
7 * Copyright (c) 2012 Frantisek Princ
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
14 * - Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * - Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * - The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 /** @addtogroup lwext4
39 * @brief Ext4 data structure definitions.
45 #include "ext4_config.h"
46 #include "ext4_blockdev.h"
52 * Structure of the super block
55 uint32_t inodes_count; /* I-nodes count */
56 uint32_t blocks_count_lo; /* Blocks count */
57 uint32_t reserved_blocks_count_lo; /* Reserved blocks count */
58 uint32_t free_blocks_count_lo; /* Free blocks count */
59 uint32_t free_inodes_count; /* Free inodes count */
60 uint32_t first_data_block; /* First Data Block */
61 uint32_t log_block_size; /* Block size */
62 uint32_t log_cluster_size; /* Obsoleted fragment size */
63 uint32_t blocks_per_group; /* Number of blocks per group */
64 uint32_t frags_per_group; /* Obsoleted fragments per group */
65 uint32_t inodes_per_group; /* Number of inodes per group */
66 uint32_t mount_time; /* Mount time */
67 uint32_t write_time; /* Write time */
68 uint16_t mount_count; /* Mount count */
69 uint16_t max_mount_count; /* Maximal mount count */
70 uint16_t magic; /* Magic signature */
71 uint16_t state; /* File system state */
72 uint16_t errors; /* Behavior when detecting errors */
73 uint16_t minor_rev_level; /* Minor revision level */
74 uint32_t last_check_time; /* Time of last check */
75 uint32_t check_interval; /* Maximum time between checks */
76 uint32_t creator_os; /* Creator OS */
77 uint32_t rev_level; /* Revision level */
78 uint16_t def_resuid; /* Default uid for reserved blocks */
79 uint16_t def_resgid; /* Default gid for reserved blocks */
81 /* Fields for EXT4_DYNAMIC_REV superblocks only. */
82 uint32_t first_inode; /* First non-reserved inode */
83 uint16_t inode_size; /* Size of inode structure */
84 uint16_t block_group_index; /* Block group index of this superblock */
85 uint32_t features_compatible; /* Compatible feature set */
86 uint32_t features_incompatible; /* Incompatible feature set */
87 uint32_t features_read_only; /* Readonly-compatible feature set */
88 uint8_t uuid[16]; /* 128-bit uuid for volume */
89 char volume_name[16]; /* Volume name */
90 char last_mounted[64]; /* Directory where last mounted */
91 uint32_t algorithm_usage_bitmap; /* For compression */
94 * Performance hints. Directory preallocation should only
95 * happen if the EXT4_FEATURE_COMPAT_DIR_PREALLOC flag is on.
97 uint8_t s_prealloc_blocks; /* Number of blocks to try to preallocate */
98 uint8_t s_prealloc_dir_blocks; /* Number to preallocate for dirs */
99 uint16_t s_reserved_gdt_blocks; /* Per group desc for online growth */
102 * Journaling support valid if EXT4_FEATURE_COMPAT_HAS_JOURNAL set.
104 uint8_t journal_uuid[16]; /* UUID of journal superblock */
105 uint32_t journal_inode_number; /* Inode number of journal file */
106 uint32_t journal_dev; /* Device number of journal file */
107 uint32_t last_orphan; /* Head of list of inodes to delete */
108 uint32_t hash_seed[4]; /* HTREE hash seed */
109 uint8_t default_hash_version; /* Default hash version to use */
110 uint8_t journal_backup_type;
111 uint16_t desc_size; /* Size of group descriptor */
112 uint32_t default_mount_opts; /* Default mount options */
113 uint32_t first_meta_bg; /* First metablock block group */
114 uint32_t mkfs_time; /* When the filesystem was created */
115 uint32_t journal_blocks[17]; /* Backup of the journal inode */
117 /* 64bit support valid if EXT4_FEATURE_COMPAT_64BIT */
118 uint32_t blocks_count_hi; /* Blocks count */
119 uint32_t reserved_blocks_count_hi; /* Reserved blocks count */
120 uint32_t free_blocks_count_hi; /* Free blocks count */
121 uint16_t min_extra_isize; /* All inodes have at least # bytes */
122 uint16_t want_extra_isize; /* New inodes should reserve # bytes */
123 uint32_t flags; /* Miscellaneous flags */
124 uint16_t raid_stride; /* RAID stride */
125 uint16_t mmp_interval; /* # seconds to wait in MMP checking */
126 uint64_t mmp_block; /* Block for multi-mount protection */
127 uint32_t raid_stripe_width; /* Blocks on all data disks (N * stride) */
128 uint8_t log_groups_per_flex; /* FLEX_BG group size */
129 uint8_t reserved_char_pad;
130 uint16_t reserved_pad;
131 uint64_t kbytes_written; /* Number of lifetime kilobytes written */
132 uint32_t snapshot_inum; /* I-node number of active snapshot */
133 uint32_t snapshot_id; /* Sequential ID of active snapshot */
135 snapshot_r_blocks_count; /* Reserved blocks for active snapshot's
138 snapshot_list; /* I-node number of the head of the on-disk snapshot
140 uint32_t error_count; /* Number of file system errors */
141 uint32_t first_error_time; /* First time an error happened */
142 uint32_t first_error_ino; /* I-node involved in first error */
143 uint64_t first_error_block; /* Block involved of first error */
144 uint8_t first_error_func[32]; /* Function where the error happened */
145 uint32_t first_error_line; /* Line number where error happened */
146 uint32_t last_error_time; /* Most recent time of an error */
147 uint32_t last_error_ino; /* I-node involved in last error */
148 uint32_t last_error_line; /* Line number where error happened */
149 uint64_t last_error_block; /* Block involved of last error */
150 uint8_t last_error_func[32]; /* Function where the error happened */
151 uint8_t mount_opts[64];
152 uint32_t padding[112]; /* Padding to the end of the block */
153 } __attribute__((packed));
155 #define EXT4_SUPERBLOCK_MAGIC 0xEF53
156 #define EXT4_SUPERBLOCK_SIZE 1024
157 #define EXT4_SUPERBLOCK_OFFSET 1024
159 #define EXT4_SUPERBLOCK_OS_LINUX 0
160 #define EXT4_SUPERBLOCK_OS_HURD 1
163 * Misc. filesystem flags
165 #define EXT4_SUPERBLOCK_FLAGS_SIGNED_HASH 0x0001
166 #define EXT4_SUPERBLOCK_FLAGS_UNSIGNED_HASH 0x0002
167 #define EXT4_SUPERBLOCK_FLAGS_TEST_FILESYS 0x0004
171 #define EXT4_SUPERBLOCK_STATE_VALID_FS 0x0001 /* Unmounted cleanly */
172 #define EXT4_SUPERBLOCK_STATE_ERROR_FS 0x0002 /* Errors detected */
173 #define EXT4_SUPERBLOCK_STATE_ORPHAN_FS 0x0004 /* Orphans being recovered */
176 * Behaviour when errors detected
178 #define EXT4_SUPERBLOCK_ERRORS_CONTINUE 1 /* Continue execution */
179 #define EXT4_SUPERBLOCK_ERRORS_RO 2 /* Remount fs read-only */
180 #define EXT4_SUPERBLOCK_ERRORS_PANIC 3 /* Panic */
181 #define EXT4_SUPERBLOCK_ERRORS_DEFAULT EXT4_ERRORS_CONTINUE
184 * Compatible features
186 #define EXT4_FEATURE_COMPAT_DIR_PREALLOC 0x0001
187 #define EXT4_FEATURE_COMPAT_IMAGIC_INODES 0x0002
188 #define EXT4_FEATURE_COMPAT_HAS_JOURNAL 0x0004
189 #define EXT4_FEATURE_COMPAT_EXT_ATTR 0x0008
190 #define EXT4_FEATURE_COMPAT_RESIZE_INODE 0x0010
191 #define EXT4_FEATURE_COMPAT_DIR_INDEX 0x0020
194 * Read-only compatible features
196 #define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001
197 #define EXT4_FEATURE_RO_COMPAT_LARGE_FILE 0x0002
198 #define EXT4_FEATURE_RO_COMPAT_BTREE_DIR 0x0004
199 #define EXT4_FEATURE_RO_COMPAT_HUGE_FILE 0x0008
200 #define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010
201 #define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020
202 #define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040
203 #define EXT4_FEATURE_RO_COMPAT_QUOTA 0x0100
204 #define EXT4_FEATURE_RO_COMPAT_BIGALLOC 0x0200
205 #define EXT4_FEATURE_RO_COMPAT_METADATA_CSUM 0x0400
208 * Incompatible features
210 #define EXT4_FEATURE_INCOMPAT_COMPRESSION 0x0001
211 #define EXT4_FEATURE_INCOMPAT_FILETYPE 0x0002
212 #define EXT4_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */
213 #define EXT4_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */
214 #define EXT4_FEATURE_INCOMPAT_META_BG 0x0010
215 #define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents support */
216 #define EXT4_FEATURE_INCOMPAT_64BIT 0x0080
217 #define EXT4_FEATURE_INCOMPAT_MMP 0x0100
218 #define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200
219 #define EXT4_FEATURE_INCOMPAT_EA_INODE 0x0400 /* EA in inode */
220 #define EXT4_FEATURE_INCOMPAT_DIRDATA 0x1000 /* data in dirent */
221 #define EXT4_FEATURE_INCOMPAT_BG_USE_META_CSUM 0x2000 /* use crc32c for bg */
222 #define EXT4_FEATURE_INCOMPAT_LARGEDIR 0x4000 /* >2GB or 3-lvl htree */
223 #define EXT4_FEATURE_INCOMPAT_INLINE_DATA 0x8000 /* data in inode */
226 * EXT2 supported feature set
228 #define EXT2_FEATURE_COMPAT_SUPP 0x0000
230 #define EXT2_FEATURE_INCOMPAT_SUPP \
231 (EXT4_FEATURE_INCOMPAT_FILETYPE | EXT4_FEATURE_INCOMPAT_META_BG)
233 #define EXT2_FEATURE_RO_COMPAT_SUPP \
234 (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER | \
235 EXT4_FEATURE_RO_COMPAT_LARGE_FILE | EXT4_FEATURE_RO_COMPAT_BTREE_DIR)
238 * EXT3 supported feature set
240 #define EXT3_FEATURE_COMPAT_SUPP (EXT4_FEATURE_COMPAT_DIR_INDEX)
242 #define EXT3_FEATURE_INCOMPAT_SUPP \
243 (EXT4_FEATURE_INCOMPAT_FILETYPE | EXT4_FEATURE_INCOMPAT_META_BG)
245 #define EXT3_FEATURE_RO_COMPAT_SUPP \
246 (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER | \
247 EXT4_FEATURE_RO_COMPAT_LARGE_FILE | EXT4_FEATURE_RO_COMPAT_BTREE_DIR)
250 * EXT4 supported feature set
252 #define EXT4_FEATURE_COMPAT_SUPP (EXT4_FEATURE_COMPAT_DIR_INDEX)
254 #define EXT4_FEATURE_INCOMPAT_SUPP \
255 (EXT4_FEATURE_INCOMPAT_FILETYPE | EXT4_FEATURE_INCOMPAT_META_BG | \
256 EXT4_FEATURE_INCOMPAT_EXTENTS | EXT4_FEATURE_INCOMPAT_FLEX_BG | \
257 EXT4_FEATURE_INCOMPAT_64BIT)
259 #define EXT4_FEATURE_RO_COMPAT_SUPP \
260 (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER | \
261 EXT4_FEATURE_RO_COMPAT_LARGE_FILE | EXT4_FEATURE_RO_COMPAT_GDT_CSUM | \
262 EXT4_FEATURE_RO_COMPAT_DIR_NLINK | \
263 EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE | \
264 EXT4_FEATURE_RO_COMPAT_BTREE_DIR | EXT4_FEATURE_RO_COMPAT_HUGE_FILE)
267 * RECOVER - journaling in lwext4 is not supported
268 * (probably won't be ever...)
269 * MMP - multi-mout protection (impossible scenario)
271 #define FEATURE_INCOMPAT_IGNORED \
272 EXT4_FEATURE_INCOMPAT_RECOVER | EXT4_FEATURE_INCOMPAT_MMP
275 /*TODO: Features incompatible to implement*/
276 #define EXT4_FEATURE_INCOMPAT_SUPP
277 (EXT4_FEATURE_INCOMPAT_INLINE_DATA)
279 /*TODO: Features read only to implement*/
280 #define EXT4_FEATURE_RO_COMPAT_SUPP
281 EXT4_FEATURE_RO_COMPAT_BIGALLOC |\
282 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM|\
283 EXT4_FEATURE_RO_COMPAT_QUOTA)
287 struct ext4_blockdev *bdev;
288 struct ext4_sblock sb;
290 uint64_t inode_block_limits[4];
291 uint64_t inode_blocks_per_level[4];
293 uint32_t last_inode_bg_id;
296 /* Inode table/bitmap not in use */
297 #define EXT4_BLOCK_GROUP_INODE_UNINIT 0x0001
298 /* Block bitmap not in use */
299 #define EXT4_BLOCK_GROUP_BLOCK_UNINIT 0x0002
300 /* On-disk itable initialized to zero */
301 #define EXT4_BLOCK_GROUP_ITABLE_ZEROED 0x0004
304 * Structure of a blocks group descriptor
307 uint32_t block_bitmap_lo; /* Blocks bitmap block */
308 uint32_t inode_bitmap_lo; /* Inodes bitmap block */
309 uint32_t inode_table_first_block_lo; /* Inodes table block */
310 uint16_t free_blocks_count_lo; /* Free blocks count */
311 uint16_t free_inodes_count_lo; /* Free inodes count */
312 uint16_t used_dirs_count_lo; /* Directories count */
313 uint16_t flags; /* EXT4_BG_flags (INODE_UNINIT, etc) */
314 uint32_t exclude_bitmap_lo; /* Exclude bitmap for snapshots */
315 uint16_t block_bitmap_csum_lo; /* crc32c(s_uuid+grp_num+bbitmap) LE */
316 uint16_t inode_bitmap_csum_lo; /* crc32c(s_uuid+grp_num+ibitmap) LE */
317 uint16_t itable_unused_lo; /* Unused inodes count */
318 uint16_t checksum; /* crc16(sb_uuid+group+desc) */
320 uint32_t block_bitmap_hi; /* Blocks bitmap block MSB */
321 uint32_t inode_bitmap_hi; /* I-nodes bitmap block MSB */
322 uint32_t inode_table_first_block_hi; /* I-nodes table block MSB */
323 uint16_t free_blocks_count_hi; /* Free blocks count MSB */
324 uint16_t free_inodes_count_hi; /* Free i-nodes count MSB */
325 uint16_t used_dirs_count_hi; /* Directories count MSB */
326 uint16_t itable_unused_hi; /* Unused inodes count MSB */
327 uint32_t exclude_bitmap_hi; /* Exclude bitmap block MSB */
328 uint16_t block_bitmap_csum_hi; /* crc32c(s_uuid+grp_num+bbitmap) BE */
329 uint16_t inode_bitmap_csum_hi; /* crc32c(s_uuid+grp_num+ibitmap) BE */
330 uint32_t reserved; /* Padding */
333 struct ext4_block_group_ref {
334 struct ext4_block block;
335 struct ext4_bgroup *block_group;
341 #define EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE 32
342 #define EXT4_MAX_BLOCK_GROUP_DESCRIPTOR_SIZE 64
344 #define EXT4_MIN_BLOCK_SIZE 1024 /* 1 KiB */
345 #define EXT4_MAX_BLOCK_SIZE 65536 /* 64 KiB */
346 #define EXT4_REV0_INODE_SIZE 128
348 #define EXT4_INODE_BLOCK_SIZE 512
350 #define EXT4_INODE_DIRECT_BLOCK_COUNT 12
351 #define EXT4_INODE_INDIRECT_BLOCK EXT4_INODE_DIRECT_BLOCK_COUNT
352 #define EXT4_INODE_DOUBLE_INDIRECT_BLOCK (EXT4_INODE_INDIRECT_BLOCK + 1)
353 #define EXT4_INODE_TRIPPLE_INDIRECT_BLOCK (EXT4_INODE_DOUBLE_INDIRECT_BLOCK + 1)
354 #define EXT4_INODE_BLOCKS (EXT4_INODE_TRIPPLE_INDIRECT_BLOCK + 1)
355 #define EXT4_INODE_INDIRECT_BLOCK_COUNT \
356 (EXT4_INODE_BLOCKS - EXT4_INODE_DIRECT_BLOCK_COUNT)
359 * Structure of an inode on the disk
362 uint16_t mode; /* File mode */
363 uint16_t uid; /* Low 16 bits of owner uid */
364 uint32_t size_lo; /* Size in bytes */
365 uint32_t access_time; /* Access time */
366 uint32_t change_inode_time; /* I-node change time */
367 uint32_t modification_time; /* Modification time */
368 uint32_t deletion_time; /* Deletion time */
369 uint16_t gid; /* Low 16 bits of group id */
370 uint16_t links_count; /* Links count */
371 uint32_t blocks_count_lo; /* Blocks count */
372 uint32_t flags; /* File flags */
373 uint32_t unused_osd1; /* OS dependent - not used in HelenOS */
374 uint32_t blocks[EXT4_INODE_BLOCKS]; /* Pointers to blocks */
375 uint32_t generation; /* File version (for NFS) */
376 uint32_t file_acl_lo; /* File ACL */
378 uint32_t obso_faddr; /* Obsoleted fragment address */
382 uint16_t blocks_high;
383 uint16_t file_acl_high;
395 } __attribute__((packed)) osd2;
397 uint16_t extra_isize;
399 uint32_t ctime_extra; /* Extra change time (nsec << 2 | epoch) */
400 uint32_t mtime_extra; /* Extra Modification time (nsec << 2 | epoch) */
401 uint32_t atime_extra; /* Extra Access time (nsec << 2 | epoch) */
402 uint32_t crtime; /* File creation time */
404 crtime_extra; /* Extra file creation time (nsec << 2 | epoch) */
405 uint32_t version_hi; /* High 32 bits for 64-bit version */
406 } __attribute__((packed));
408 #define EXT4_INODE_MODE_FIFO 0x1000
409 #define EXT4_INODE_MODE_CHARDEV 0x2000
410 #define EXT4_INODE_MODE_DIRECTORY 0x4000
411 #define EXT4_INODE_MODE_BLOCKDEV 0x6000
412 #define EXT4_INODE_MODE_FILE 0x8000
413 #define EXT4_INODE_MODE_SOFTLINK 0xA000
414 #define EXT4_INODE_MODE_SOCKET 0xC000
415 #define EXT4_INODE_MODE_TYPE_MASK 0xF000
420 #define EXT4_INODE_FLAG_SECRM 0x00000001 /* Secure deletion */
421 #define EXT4_INODE_FLAG_UNRM 0x00000002 /* Undelete */
422 #define EXT4_INODE_FLAG_COMPR 0x00000004 /* Compress file */
423 #define EXT4_INODE_FLAG_SYNC 0x00000008 /* Synchronous updates */
424 #define EXT4_INODE_FLAG_IMMUTABLE 0x00000010 /* Immutable file */
425 #define EXT4_INODE_FLAG_APPEND 0x00000020 /* writes to file may only append */
426 #define EXT4_INODE_FLAG_NODUMP 0x00000040 /* do not dump file */
427 #define EXT4_INODE_FLAG_NOATIME 0x00000080 /* do not update atime */
429 /* Compression flags */
430 #define EXT4_INODE_FLAG_DIRTY 0x00000100
431 #define EXT4_INODE_FLAG_COMPRBLK \
432 0x00000200 /* One or more compressed clusters */
433 #define EXT4_INODE_FLAG_NOCOMPR 0x00000400 /* Don't compress */
434 #define EXT4_INODE_FLAG_ECOMPR 0x00000800 /* Compression error */
436 #define EXT4_INODE_FLAG_INDEX 0x00001000 /* hash-indexed directory */
437 #define EXT4_INODE_FLAG_IMAGIC 0x00002000 /* AFS directory */
438 #define EXT4_INODE_FLAG_JOURNAL_DATA \
439 0x00004000 /* File data should be journaled */
440 #define EXT4_INODE_FLAG_NOTAIL 0x00008000 /* File tail should not be merged */
441 #define EXT4_INODE_FLAG_DIRSYNC \
442 0x00010000 /* Dirsync behaviour (directories only) */
443 #define EXT4_INODE_FLAG_TOPDIR 0x00020000 /* Top of directory hierarchies */
444 #define EXT4_INODE_FLAG_HUGE_FILE 0x00040000 /* Set to each huge file */
445 #define EXT4_INODE_FLAG_EXTENTS 0x00080000 /* Inode uses extents */
446 #define EXT4_INODE_FLAG_EA_INODE 0x00200000 /* Inode used for large EA */
447 #define EXT4_INODE_FLAG_EOFBLOCKS 0x00400000 /* Blocks allocated beyond EOF */
448 #define EXT4_INODE_FLAG_RESERVED 0x80000000 /* reserved for ext4 lib */
450 #define EXT4_INODE_ROOT_INDEX 2
452 struct ext4_inode_ref {
453 struct ext4_block block;
454 struct ext4_inode *inode;
460 #define EXT4_DIRECTORY_FILENAME_LEN 255
462 /**@brief Directory entry types. */
463 enum { EXT4_DIRENTRY_UNKNOWN = 0,
464 EXT4_DIRENTRY_REG_FILE,
466 EXT4_DIRENTRY_CHRDEV,
467 EXT4_DIRENTRY_BLKDEV,
470 EXT4_DIRENTRY_SYMLINK };
472 union ext4_directory_entry_ll_internal {
473 uint8_t name_length_high; /* Higher 8 bits of name length */
474 uint8_t inode_type; /* Type of referenced inode (in rev >= 0.5) */
475 } __attribute__((packed));
478 * Linked list directory entry structure
480 struct ext4_directory_entry_ll {
481 uint32_t inode; /* I-node for the entry */
482 uint16_t entry_length; /* Distance to the next directory entry */
483 uint8_t name_length; /* Lower 8 bits of name length */
485 union ext4_directory_entry_ll_internal in;
487 uint8_t name[EXT4_DIRECTORY_FILENAME_LEN]; /* Entry name */
488 } __attribute__((packed));
490 struct ext4_directory_iterator {
491 struct ext4_inode_ref *inode_ref;
492 struct ext4_block current_block;
493 uint64_t current_offset;
494 struct ext4_directory_entry_ll *current;
497 struct ext4_directory_search_result {
498 struct ext4_block block;
499 struct ext4_directory_entry_ll *dentry;
502 /* Structures for indexed directory */
504 struct ext4_directory_dx_countlimit {
509 struct ext4_directory_dx_dot_entry {
511 uint16_t entry_length;
517 struct ext4_directory_dx_root_info {
518 uint32_t reserved_zero;
519 uint8_t hash_version;
521 uint8_t indirect_levels;
522 uint8_t unused_flags;
525 struct ext4_directory_dx_entry {
530 struct ext4_directory_dx_root {
531 struct ext4_directory_dx_dot_entry dots[2];
532 struct ext4_directory_dx_root_info info;
533 struct ext4_directory_dx_entry entries[];
536 struct ext4_fake_directory_entry {
538 uint16_t entry_length;
543 struct ext4_directory_dx_node {
544 struct ext4_fake_directory_entry fake;
545 struct ext4_directory_dx_entry entries[];
548 struct ext4_directory_dx_block {
549 struct ext4_block block;
550 struct ext4_directory_dx_entry *entries;
551 struct ext4_directory_dx_entry *position;
554 #define EXT4_ERR_BAD_DX_DIR (-25000)
556 #define EXT4_LINK_MAX 65000
558 #define EXT4_BAD_INO 1
559 #define EXT4_ROOT_INO 2
560 #define EXT4_BOOT_LOADER_INO 5
561 #define EXT4_UNDEL_DIR_INO 6
562 #define EXT4_RESIZE_INO 7
563 #define EXT4_JOURNAL_INO 8
565 #define EXT4_GOOD_OLD_FIRST_INO 11
567 #define EXT4_EXT_UNWRITTEN_MASK (1L << 15)
569 #define EXT4_EXT_MAX_LEN_WRITTEN (1L << 15)
570 #define EXT4_EXT_MAX_LEN_UNWRITTEN \
571 (EXT4_EXT_MAX_LEN_WRITTEN - 1)
573 #define EXT4_EXT_GET_LEN(ex) to_le16((ex)->block_count)
574 #define EXT4_EXT_GET_LEN_UNWRITTEN(ex) \
575 (EXT4_EXT_GET_LEN(ex) &= ~(EXT4_EXT_UNWRITTEN_MASK))
576 #define EXT4_EXT_SET_LEN(ex, count) \
577 ((ex)->block_count = to_le16(count))
579 #define EXT4_EXT_IS_UNWRITTEN(ex) \
580 (EXT4_EXT_GET_LEN(ex) > EXT4_EXT_MAX_LEN_WRITTEN)
581 #define EXT4_EXT_SET_UNWRITTEN(ex) \
582 ((ex)->block_count |= to_le16(EXT4_EXT_UNWRITTEN_MASK))
583 #define EXT4_EXT_SET_WRITTEN(ex) \
584 ((ex)->block_count &= ~(to_le16(EXT4_EXT_UNWRITTEN_MASK)))
587 * This is the extent on-disk structure.
588 * It's used at the bottom of the tree.
591 uint32_t first_block; /* First logical block extent covers */
592 uint16_t block_count; /* Number of blocks covered by extent */
593 uint16_t start_hi; /* High 16 bits of physical block */
594 uint32_t start_lo; /* Low 32 bits of physical block */
598 * This is index on-disk structure.
599 * It's used at all the levels except the bottom.
601 struct ext4_extent_index {
602 uint32_t first_block; /* Index covers logical blocks from 'block' */
605 * Pointer to the physical block of the next
606 * level. leaf or next index could be there
607 * high 16 bits of physical block
615 * Each block (leaves and indexes), even inode-stored has header.
617 struct ext4_extent_header {
619 uint16_t entries_count; /* Number of valid entries */
620 uint16_t max_entries_count; /* Capacity of store in entries */
621 uint16_t depth; /* Has tree real underlying blocks? */
622 uint32_t generation; /* generation of the tree */
625 struct ext4_extent_path {
626 struct ext4_block block;
628 struct ext4_extent_header *header;
629 struct ext4_extent_index *index;
630 struct ext4_extent *extent;
633 #define EXT4_EXTENT_MAGIC 0xF30A
635 #define EXT4_EXTENT_FIRST(header) \
636 ((struct ext4_extent *)(((char *)(header)) + \
637 sizeof(struct ext4_extent_header)))
639 #define EXT4_EXTENT_FIRST_INDEX(header) \
640 ((struct ext4_extent_index *)(((char *)(header)) + \
641 sizeof(struct ext4_extent_header)))
643 /* EXT3 HTree directory indexing */
644 #define EXT2_HTREE_LEGACY 0
645 #define EXT2_HTREE_HALF_MD4 1
646 #define EXT2_HTREE_TEA 2
647 #define EXT2_HTREE_LEGACY_UNSIGNED 3
648 #define EXT2_HTREE_HALF_MD4_UNSIGNED 4
649 #define EXT2_HTREE_TEA_UNSIGNED 5
651 #define EXT2_HTREE_EOF 0x7FFFFFFFUL
653 struct ext4_hash_info {
656 uint32_t hash_version;
657 const uint32_t *seed;
660 /* Extended Attribute(EA) */
662 /* Magic value in attribute blocks */
663 #define EXT4_XATTR_MAGIC 0xEA020000
665 /* Maximum number of references to one attribute block */
666 #define EXT4_XATTR_REFCOUNT_MAX 1024
669 #define EXT4_XATTR_INDEX_USER 1
670 #define EXT4_XATTR_INDEX_POSIX_ACL_ACCESS 2
671 #define EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT 3
672 #define EXT4_XATTR_INDEX_TRUSTED 4
673 #define EXT4_XATTR_INDEX_LUSTRE 5
674 #define EXT4_XATTR_INDEX_SECURITY 6
675 #define EXT4_XATTR_INDEX_SYSTEM 7
676 #define EXT4_XATTR_INDEX_RICHACL 8
677 #define EXT4_XATTR_INDEX_ENCRYPTION 9
679 struct ext4_xattr_header {
680 uint32_t h_magic; /* magic number for identification */
681 uint32_t h_refcount; /* reference count */
682 uint32_t h_blocks; /* number of disk blocks used */
683 uint32_t h_hash; /* hash value of all attributes */
684 uint32_t h_checksum; /* crc32c(uuid+id+xattrblock) */
685 /* id = inum if refcount=1, blknum otherwise */
686 uint32_t h_reserved[3]; /* zero right now */
687 } __attribute__((packed));
689 struct ext4_xattr_ibody_header {
690 uint32_t h_magic; /* magic number for identification */
691 } __attribute__((packed));
693 struct ext4_xattr_entry {
694 uint8_t e_name_len; /* length of name */
695 uint8_t e_name_index; /* attribute name index */
696 uint16_t e_value_offs; /* offset in disk block of value */
697 uint32_t e_value_block; /* disk block attribute is stored on (n/i) */
698 uint32_t e_value_size; /* size of attribute value */
699 uint32_t e_hash; /* hash value of name and value */
700 } __attribute__((packed));
702 struct ext4_xattr_item {
709 RB_ENTRY(ext4_xattr_item) node;
712 struct ext4_xattr_ref {
714 struct ext4_block block;
715 struct ext4_inode_ref *inode_ref;
721 struct ext4_xattr_item *iter_from;
723 RB_HEAD(ext4_xattr_tree,
724 ext4_xattr_item) root;
727 #define EXT4_XATTR_ITERATE_CONT 0
728 #define EXT4_XATTR_ITERATE_STOP 1
729 #define EXT4_XATTR_ITERATE_PAUSE 2
731 #define EXT4_GOOD_OLD_INODE_SIZE 128
733 #define EXT4_XATTR_PAD_BITS 2
734 #define EXT4_XATTR_PAD (1<<EXT4_XATTR_PAD_BITS)
735 #define EXT4_XATTR_ROUND (EXT4_XATTR_PAD-1)
736 #define EXT4_XATTR_LEN(name_len) \
737 (((name_len) + EXT4_XATTR_ROUND + \
738 sizeof(struct ext4_xattr_entry)) & ~EXT4_XATTR_ROUND)
739 #define EXT4_XATTR_NEXT(entry) \
740 ((struct ext4_xattr_entry *)( \
741 (char *)(entry) + EXT4_XATTR_LEN((entry)->e_name_len)))
742 #define EXT4_XATTR_SIZE(size) \
743 (((size) + EXT4_XATTR_ROUND) & ~EXT4_XATTR_ROUND)
744 #define EXT4_XATTR_NAME(entry) \
745 ((char *)((entry) + 1))
747 #define EXT4_XATTR_IHDR(raw_inode) \
748 ((struct ext4_xattr_ibody_header *) \
749 ((char *)raw_inode + \
750 EXT4_GOOD_OLD_INODE_SIZE + \
751 (raw_inode)->extra_isize))
752 #define EXT4_XATTR_IFIRST(hdr) \
753 ((struct ext4_xattr_entry *)((hdr)+1))
755 #define EXT4_XATTR_BHDR(block) \
756 ((struct ext4_xattr_header *)((block)->data))
757 #define EXT4_XATTR_ENTRY(ptr) \
758 ((struct ext4_xattr_entry *)(ptr))
759 #define EXT4_XATTR_BFIRST(block) \
760 EXT4_XATTR_ENTRY(EXT4_XATTR_BHDR(block)+1)
761 #define EXT4_XATTR_IS_LAST_ENTRY(entry) \
762 (*(uint32_t *)(entry) == 0)
764 #define EXT4_ZERO_XATTR_VALUE ((void *)-1)
766 /*****************************************************************************/
768 #ifdef CONFIG_BIG_ENDIAN
769 static inline uint64_t to_le64(uint64_t n)
771 return ((n & 0xff) << 56) | ((n & 0xff00) << 40) |
772 ((n & 0xff0000) << 24) | ((n & 0xff000000LL) << 8) |
773 ((n & 0xff00000000LL) >> 8) | ((n & 0xff0000000000LL) >> 24) |
774 ((n & 0xff000000000000LL) >> 40) |
775 ((n & 0xff00000000000000LL) >> 56);
778 static inline uint32_t to_le32(uint32_t n)
780 return ((n & 0xff) << 24) | ((n & 0xff00) << 8) |
781 ((n & 0xff0000) >> 8) | ((n & 0xff000000) >> 24);
784 static inline uint16_t to_le16(uint16_t n)
786 return ((n & 0xff) << 8) | ((n & 0xff00) >> 8);
790 #define to_le64(_n) _n
791 #define to_le32(_n) _n
792 #define to_le16(_n) _n
795 /****************************Access macros to ext4 structures*****************/
797 #define ext4_get32(s, f) to_le32((s)->f)
798 #define ext4_get16(s, f) to_le16((s)->f)
799 #define ext4_get8(s, f) (s)->f
801 #define ext4_set32(s, f, v) \
803 (s)->f = to_le32(v); \
805 #define ext4_set16(s, f, v) \
807 (s)->f = to_le16(v); \
810 (s, f, v) do { (s)->f = (v); } \
813 #endif /* EXT4_TYPES_H_ */