Improve include policy
[lwext4.git] / lwext4 / ext4_types.h
1 /*
2  * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
3  *
4  *
5  * HelenOS:
6  * Copyright (c) 2012 Martin Sucha
7  * Copyright (c) 2012 Frantisek Princ
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *
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.
21  *
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.
32  */
33
34 /** @addtogroup lwext4
35  * @{
36  */
37 /**
38  * @file  ext4_types.h
39  * @brief Ext4 data structure definitions.
40  */
41
42 #ifndef EXT4_TYPES_H_
43 #define EXT4_TYPES_H_
44
45 #include "ext4_config.h"
46 #include "ext4_blockdev.h"
47
48 #include <stdint.h>
49
50 /*
51  * Structure of the super block
52  */
53 struct ext4_sblock {
54     uint32_t inodes_count;             /* I-nodes count */
55     uint32_t blocks_count_lo;          /* Blocks count */
56     uint32_t reserved_blocks_count_lo; /* Reserved blocks count */
57     uint32_t free_blocks_count_lo;     /* Free blocks count */
58     uint32_t free_inodes_count;        /* Free inodes count */
59     uint32_t first_data_block;         /* First Data Block */
60     uint32_t log_block_size;           /* Block size */
61     uint32_t log_cluster_size;         /* Obsoleted fragment size */
62     uint32_t blocks_per_group;         /* Number of blocks per group */
63     uint32_t frags_per_group;          /* Obsoleted fragments per group */
64     uint32_t inodes_per_group;         /* Number of inodes per group */
65     uint32_t mount_time;               /* Mount time */
66     uint32_t write_time;               /* Write time */
67     uint16_t mount_count;              /* Mount count */
68     uint16_t max_mount_count;          /* Maximal mount count */
69     uint16_t magic;                    /* Magic signature */
70     uint16_t state;                    /* File system state */
71     uint16_t errors;                   /* Behaviour when detecting errors */
72     uint16_t minor_rev_level;          /* Minor revision level */
73     uint32_t last_check_time;          /* Time of last check */
74     uint32_t check_interval;           /* Maximum time between checks */
75     uint32_t creator_os;               /* Creator OS */
76     uint32_t rev_level;                /* Revision level */
77     uint16_t def_resuid;               /* Default uid for reserved blocks */
78     uint16_t def_resgid;               /* Default gid for reserved blocks */
79
80     /* Fields for EXT4_DYNAMIC_REV superblocks only. */
81     uint32_t first_inode;            /* First non-reserved inode */
82     uint16_t inode_size;             /* Size of inode structure */
83     uint16_t block_group_index;      /* Block group index of this superblock */
84     uint32_t features_compatible;    /* Compatible feature set */
85     uint32_t features_incompatible;  /* Incompatible feature set */
86     uint32_t features_read_only;     /* Readonly-compatible feature set */
87     uint8_t uuid[16];                /* 128-bit uuid for volume */
88     char volume_name[16];            /* Volume name */
89     char last_mounted[64];           /* Directory where last mounted */
90     uint32_t algorithm_usage_bitmap; /* For compression */
91
92     /*
93      * Performance hints. Directory preallocation should only
94      * happen if the EXT4_FEATURE_COMPAT_DIR_PREALLOC flag is on.
95      */
96     uint8_t s_prealloc_blocks;      /* Number of blocks to try to preallocate */
97     uint8_t s_prealloc_dir_blocks;  /* Number to preallocate for dirs */
98     uint16_t s_reserved_gdt_blocks; /* Per group desc for online growth */
99
100     /*
101      * Journaling support valid if EXT4_FEATURE_COMPAT_HAS_JOURNAL set.
102      */
103     uint8_t journal_uuid[16];      /* UUID of journal superblock */
104     uint32_t journal_inode_number; /* Inode number of journal file */
105     uint32_t journal_dev;          /* Device number of journal file */
106     uint32_t last_orphan;          /* Head of list of inodes to delete */
107     uint32_t hash_seed[4];         /* HTREE hash seed */
108     uint8_t default_hash_version;  /* Default hash version to use */
109     uint8_t journal_backup_type;
110     uint16_t desc_size;          /* Size of group descriptor */
111     uint32_t default_mount_opts; /* Default mount options */
112     uint32_t first_meta_bg;      /* First metablock block group */
113     uint32_t mkfs_time;          /* When the filesystem was created */
114     uint32_t journal_blocks[17]; /* Backup of the journal inode */
115
116     /* 64bit support valid if EXT4_FEATURE_COMPAT_64BIT */
117     uint32_t blocks_count_hi;          /* Blocks count */
118     uint32_t reserved_blocks_count_hi; /* Reserved blocks count */
119     uint32_t free_blocks_count_hi;     /* Free blocks count */
120     uint16_t min_extra_isize;          /* All inodes have at least # bytes */
121     uint16_t want_extra_isize;         /* New inodes should reserve # bytes */
122     uint32_t flags;                    /* Miscellaneous flags */
123     uint16_t raid_stride;              /* RAID stride */
124     uint16_t mmp_interval;             /* # seconds to wait in MMP checking */
125     uint64_t mmp_block;                /* Block for multi-mount protection */
126     uint32_t raid_stripe_width;  /* Blocks on all data disks (N * stride) */
127     uint8_t log_groups_per_flex; /* FLEX_BG group size */
128     uint8_t reserved_char_pad;
129     uint16_t reserved_pad;
130     uint64_t kbytes_written;          /* Number of lifetime kilobytes written */
131     uint32_t snapshot_inum;           /* I-node number of active snapshot */
132     uint32_t snapshot_id;             /* Sequential ID of active snapshot */
133     uint64_t snapshot_r_blocks_count; /* Reserved blocks for active snapshot's
134                                          future use */
135     uint32_t snapshot_list; /* I-node number of the head of the on-disk snapshot
136                                list */
137     uint32_t error_count;   /* Number of file system errors */
138     uint32_t first_error_time;    /* First time an error happened */
139     uint32_t first_error_ino;     /* I-node involved in first error */
140     uint64_t first_error_block;   /* Block involved of first error */
141     uint8_t first_error_func[32]; /* Function where the error happened */
142     uint32_t first_error_line;    /* Line number where error happened */
143     uint32_t last_error_time;     /* Most recent time of an error */
144     uint32_t last_error_ino;      /* I-node involved in last error */
145     uint32_t last_error_line;     /* Line number where error happened */
146     uint64_t last_error_block;    /* Block involved of last error */
147     uint8_t last_error_func[32];  /* Function where the error happened */
148     uint8_t mount_opts[64];
149     uint32_t padding[112]; /* Padding to the end of the block */
150 } __attribute__((packed));
151
152 #define EXT4_SUPERBLOCK_MAGIC 0xEF53
153 #define EXT4_SUPERBLOCK_SIZE 1024
154 #define EXT4_SUPERBLOCK_OFFSET 1024
155
156 #define EXT4_SUPERBLOCK_OS_LINUX 0
157 #define EXT4_SUPERBLOCK_OS_HURD 1
158
159 /*
160  * Misc. filesystem flags
161  */
162 #define EXT4_SUPERBLOCK_FLAGS_SIGNED_HASH 0x0001
163 #define EXT4_SUPERBLOCK_FLAGS_UNSIGNED_HASH 0x0002
164 #define EXT4_SUPERBLOCK_FLAGS_TEST_FILESYS 0x0004
165 /*
166  * Filesystem states
167  */
168 #define EXT4_SUPERBLOCK_STATE_VALID_FS 0x0001  /* Unmounted cleanly */
169 #define EXT4_SUPERBLOCK_STATE_ERROR_FS 0x0002  /* Errors detected */
170 #define EXT4_SUPERBLOCK_STATE_ORPHAN_FS 0x0004 /* Orphans being recovered */
171
172 /*
173  * Behaviour when errors detected
174  */
175 #define EXT4_SUPERBLOCK_ERRORS_CONTINUE 1 /* Continue execution */
176 #define EXT4_SUPERBLOCK_ERRORS_RO 2       /* Remount fs read-only */
177 #define EXT4_SUPERBLOCK_ERRORS_PANIC 3    /* Panic */
178 #define EXT4_SUPERBLOCK_ERRORS_DEFAULT EXT4_ERRORS_CONTINUE
179
180 /*
181  * Compatible features
182  */
183 #define EXT4_FEATURE_COMPAT_DIR_PREALLOC 0x0001
184 #define EXT4_FEATURE_COMPAT_IMAGIC_INODES 0x0002
185 #define EXT4_FEATURE_COMPAT_HAS_JOURNAL 0x0004
186 #define EXT4_FEATURE_COMPAT_EXT_ATTR 0x0008
187 #define EXT4_FEATURE_COMPAT_RESIZE_INODE 0x0010
188 #define EXT4_FEATURE_COMPAT_DIR_INDEX 0x0020
189
190 /*
191  * Read-only compatible features
192  */
193 #define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001
194 #define EXT4_FEATURE_RO_COMPAT_LARGE_FILE 0x0002
195 #define EXT4_FEATURE_RO_COMPAT_BTREE_DIR 0x0004
196 #define EXT4_FEATURE_RO_COMPAT_HUGE_FILE 0x0008
197 #define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010
198 #define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020
199 #define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040
200 #define EXT4_FEATURE_RO_COMPAT_QUOTA 0x0100
201 #define EXT4_FEATURE_RO_COMPAT_BIGALLOC 0x0200
202 #define EXT4_FEATURE_RO_COMPAT_METADATA_CSUM 0x0400
203
204 /*
205  * Incompatible features
206  */
207 #define EXT4_FEATURE_INCOMPAT_COMPRESSION 0x0001
208 #define EXT4_FEATURE_INCOMPAT_FILETYPE 0x0002
209 #define EXT4_FEATURE_INCOMPAT_RECOVER 0x0004     /* Needs recovery */
210 #define EXT4_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */
211 #define EXT4_FEATURE_INCOMPAT_META_BG 0x0010
212 #define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents support */
213 #define EXT4_FEATURE_INCOMPAT_64BIT 0x0080
214 #define EXT4_FEATURE_INCOMPAT_MMP 0x0100
215 #define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200
216 #define EXT4_FEATURE_INCOMPAT_EA_INODE 0x0400         /* EA in inode */
217 #define EXT4_FEATURE_INCOMPAT_DIRDATA 0x1000          /* data in dirent */
218 #define EXT4_FEATURE_INCOMPAT_BG_USE_META_CSUM 0x2000 /* use crc32c for bg */
219 #define EXT4_FEATURE_INCOMPAT_LARGEDIR 0x4000         /* >2GB or 3-lvl htree */
220 #define EXT4_FEATURE_INCOMPAT_INLINE_DATA 0x8000      /* data in inode */
221
222 /*
223  * EXT2 supported feature set
224  */
225 #define EXT2_FEATURE_COMPAT_SUPP 0x0000
226
227 #define EXT2_FEATURE_INCOMPAT_SUPP                                             \
228     (EXT4_FEATURE_INCOMPAT_FILETYPE | EXT4_FEATURE_INCOMPAT_META_BG)
229
230 #define EXT2_FEATURE_RO_COMPAT_SUPP                                            \
231     (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER | EXT4_FEATURE_RO_COMPAT_LARGE_FILE | \
232      EXT4_FEATURE_RO_COMPAT_BTREE_DIR)
233
234 /*
235  * EXT3 supported feature set
236  */
237 #define EXT3_FEATURE_COMPAT_SUPP (EXT4_FEATURE_COMPAT_DIR_INDEX)
238
239 #define EXT3_FEATURE_INCOMPAT_SUPP                                             \
240     (EXT4_FEATURE_INCOMPAT_FILETYPE | EXT4_FEATURE_INCOMPAT_META_BG)
241
242 #define EXT3_FEATURE_RO_COMPAT_SUPP                                            \
243     (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER | EXT4_FEATURE_RO_COMPAT_LARGE_FILE | \
244      EXT4_FEATURE_RO_COMPAT_BTREE_DIR)
245
246 /*
247  * EXT4 supported feature set
248  */
249 #define EXT4_FEATURE_COMPAT_SUPP (EXT4_FEATURE_COMPAT_DIR_INDEX)
250
251 #define EXT4_FEATURE_INCOMPAT_SUPP                                             \
252     (EXT4_FEATURE_INCOMPAT_FILETYPE | EXT4_FEATURE_INCOMPAT_META_BG |          \
253      EXT4_FEATURE_INCOMPAT_EXTENTS | EXT4_FEATURE_INCOMPAT_FLEX_BG |           \
254      EXT4_FEATURE_INCOMPAT_64BIT)
255
256 #define EXT4_FEATURE_RO_COMPAT_SUPP                                            \
257     (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER | EXT4_FEATURE_RO_COMPAT_LARGE_FILE | \
258      EXT4_FEATURE_RO_COMPAT_GDT_CSUM | EXT4_FEATURE_RO_COMPAT_DIR_NLINK |      \
259      EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE | EXT4_FEATURE_RO_COMPAT_BTREE_DIR |   \
260      EXT4_FEATURE_RO_COMPAT_HUGE_FILE)
261
262 /*Ignored features:
263  * RECOVER - journaling in lwext4 is not supported
264  *           (probably won,t be ever...)
265  * MMP - multi mout protection (impossible scenario)
266  * */
267 #define FEATURE_INCOMPAT_IGNORED                                               \
268     EXT4_FEATURE_INCOMPAT_RECOVER | EXT4_FEATURE_INCOMPAT_MMP
269
270 #if 0
271 /*TODO: Features incompatible to implement*/
272 #define EXT4_FEATURE_INCOMPAT_SUPP
273                      (EXT4_FEATURE_INCOMPAT_INLINE_DATA)
274
275 /*TODO: Features read only to implement*/
276 #define EXT4_FEATURE_RO_COMPAT_SUPP
277                      EXT4_FEATURE_RO_COMPAT_BIGALLOC |\
278                      EXT4_FEATURE_RO_COMPAT_METADATA_CSUM|\
279                      EXT4_FEATURE_RO_COMPAT_QUOTA)
280 #endif
281
282 struct ext4_fs {
283     struct ext4_blockdev *bdev;
284     struct ext4_sblock sb;
285
286     uint64_t inode_block_limits[4];
287     uint64_t inode_blocks_per_level[4];
288
289     uint32_t last_inode_bg_id;
290 };
291
292 /* Inode table/bitmap not in use */
293 #define EXT4_BLOCK_GROUP_INODE_UNINIT 0x0001
294 /* Block bitmap not in use */
295 #define EXT4_BLOCK_GROUP_BLOCK_UNINIT 0x0002
296 /* On-disk itable initialized to zero */
297 #define EXT4_BLOCK_GROUP_ITABLE_ZEROED 0x0004
298
299 /*
300  * Structure of a blocks group descriptor
301  */
302 struct ext4_bgroup {
303     uint32_t block_bitmap_lo;            /* Blocks bitmap block */
304     uint32_t inode_bitmap_lo;            /* Inodes bitmap block */
305     uint32_t inode_table_first_block_lo; /* Inodes table block */
306     uint16_t free_blocks_count_lo;       /* Free blocks count */
307     uint16_t free_inodes_count_lo;       /* Free inodes count */
308     uint16_t used_dirs_count_lo;         /* Directories count */
309     uint16_t flags;                      /* EXT4_BG_flags (INODE_UNINIT, etc) */
310     uint32_t exclude_bitmap_lo;          /* Exclude bitmap for snapshots */
311     uint16_t block_bitmap_csum_lo;       /* crc32c(s_uuid+grp_num+bbitmap) LE */
312     uint16_t inode_bitmap_csum_lo;       /* crc32c(s_uuid+grp_num+ibitmap) LE */
313     uint16_t itable_unused_lo;           /* Unused inodes count */
314     uint16_t checksum;                   /* crc16(sb_uuid+group+desc) */
315
316     uint32_t block_bitmap_hi;            /* Blocks bitmap block MSB */
317     uint32_t inode_bitmap_hi;            /* I-nodes bitmap block MSB */
318     uint32_t inode_table_first_block_hi; /* I-nodes table block MSB */
319     uint16_t free_blocks_count_hi;       /* Free blocks count MSB */
320     uint16_t free_inodes_count_hi;       /* Free i-nodes count MSB */
321     uint16_t used_dirs_count_hi;         /* Directories count MSB */
322     uint16_t itable_unused_hi;           /* Unused inodes count MSB */
323     uint32_t exclude_bitmap_hi;          /* Exclude bitmap block MSB */
324     uint16_t block_bitmap_csum_hi;       /* crc32c(s_uuid+grp_num+bbitmap) BE */
325     uint16_t inode_bitmap_csum_hi;       /* crc32c(s_uuid+grp_num+ibitmap) BE */
326     uint32_t reserved;                   /* Padding */
327 };
328
329 struct ext4_block_group_ref {
330     struct ext4_block block;
331     struct ext4_bgroup *block_group;
332     struct ext4_fs *fs;
333     uint32_t index;
334     bool dirty;
335 };
336
337 #define EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE 32
338 #define EXT4_MAX_BLOCK_GROUP_DESCRIPTOR_SIZE 64
339
340 #define EXT4_MIN_BLOCK_SIZE 1024  /* 1 KiB */
341 #define EXT4_MAX_BLOCK_SIZE 65536 /* 64 KiB */
342 #define EXT4_REV0_INODE_SIZE 128
343
344 #define EXT4_INODE_BLOCK_SIZE 512
345
346 #define EXT4_INODE_DIRECT_BLOCK_COUNT 12
347 #define EXT4_INODE_INDIRECT_BLOCK EXT4_INODE_DIRECT_BLOCK_COUNT
348 #define EXT4_INODE_DOUBLE_INDIRECT_BLOCK (EXT4_INODE_INDIRECT_BLOCK + 1)
349 #define EXT4_INODE_TRIPPLE_INDIRECT_BLOCK (EXT4_INODE_DOUBLE_INDIRECT_BLOCK + 1)
350 #define EXT4_INODE_BLOCKS (EXT4_INODE_TRIPPLE_INDIRECT_BLOCK + 1)
351 #define EXT4_INODE_INDIRECT_BLOCK_COUNT                                        \
352     (EXT4_INODE_BLOCKS - EXT4_INODE_DIRECT_BLOCK_COUNT)
353
354 /*
355  * Structure of an inode on the disk
356  */
357 struct ext4_inode {
358     uint16_t mode;                      /* File mode */
359     uint16_t uid;                       /* Low 16 bits of owner uid */
360     uint32_t size_lo;                   /* Size in bytes */
361     uint32_t access_time;               /* Access time */
362     uint32_t change_inode_time;         /* I-node change time */
363     uint32_t modification_time;         /* Modification time */
364     uint32_t deletion_time;             /* Deletion time */
365     uint16_t gid;                       /* Low 16 bits of group id */
366     uint16_t links_count;               /* Links count */
367     uint32_t blocks_count_lo;           /* Blocks count */
368     uint32_t flags;                     /* File flags */
369     uint32_t unused_osd1;               /* OS dependent - not used in HelenOS */
370     uint32_t blocks[EXT4_INODE_BLOCKS]; /* Pointers to blocks */
371     uint32_t generation;                /* File version (for NFS) */
372     uint32_t file_acl_lo;               /* File ACL */
373     uint32_t size_hi;
374     uint32_t obso_faddr; /* Obsoleted fragment address */
375
376     union {
377         struct {
378             uint16_t blocks_high;
379             uint16_t file_acl_high;
380             uint16_t uid_high;
381             uint16_t gid_high;
382             uint32_t reserved2;
383         } linux2;
384         struct {
385             uint16_t reserved1;
386             uint16_t mode_high;
387             uint16_t uid_high;
388             uint16_t gid_high;
389             uint32_t author;
390         } hurd2;
391     } __attribute__((packed)) osd2;
392
393     uint16_t extra_isize;
394     uint16_t pad1;
395     uint32_t ctime_extra;  /* Extra change time (nsec << 2 | epoch) */
396     uint32_t mtime_extra;  /* Extra Modification time (nsec << 2 | epoch) */
397     uint32_t atime_extra;  /* Extra Access time (nsec << 2 | epoch) */
398     uint32_t crtime;       /* File creation time */
399     uint32_t crtime_extra; /* Extra file creation time (nsec << 2 | epoch) */
400     uint32_t version_hi;   /* High 32 bits for 64-bit version */
401 } __attribute__((packed));
402
403 #define EXT4_INODE_MODE_FIFO 0x1000
404 #define EXT4_INODE_MODE_CHARDEV 0x2000
405 #define EXT4_INODE_MODE_DIRECTORY 0x4000
406 #define EXT4_INODE_MODE_BLOCKDEV 0x6000
407 #define EXT4_INODE_MODE_FILE 0x8000
408 #define EXT4_INODE_MODE_SOFTLINK 0xA000
409 #define EXT4_INODE_MODE_SOCKET 0xC000
410 #define EXT4_INODE_MODE_TYPE_MASK 0xF000
411
412 /*
413  * Inode flags
414  */
415 #define EXT4_INODE_FLAG_SECRM 0x00000001     /* Secure deletion */
416 #define EXT4_INODE_FLAG_UNRM 0x00000002      /* Undelete */
417 #define EXT4_INODE_FLAG_COMPR 0x00000004     /* Compress file */
418 #define EXT4_INODE_FLAG_SYNC 0x00000008      /* Synchronous updates */
419 #define EXT4_INODE_FLAG_IMMUTABLE 0x00000010 /* Immutable file */
420 #define EXT4_INODE_FLAG_APPEND 0x00000020  /* writes to file may only append */
421 #define EXT4_INODE_FLAG_NODUMP 0x00000040  /* do not dump file */
422 #define EXT4_INODE_FLAG_NOATIME 0x00000080 /* do not update atime */
423
424 /* Compression flags */
425 #define EXT4_INODE_FLAG_DIRTY 0x00000100
426 #define EXT4_INODE_FLAG_COMPRBLK                                               \
427     0x00000200                             /* One or more compressed clusters */
428 #define EXT4_INODE_FLAG_NOCOMPR 0x00000400 /* Don't compress */
429 #define EXT4_INODE_FLAG_ECOMPR 0x00000800  /* Compression error */
430
431 #define EXT4_INODE_FLAG_INDEX 0x00001000  /* hash-indexed directory */
432 #define EXT4_INODE_FLAG_IMAGIC 0x00002000 /* AFS directory */
433 #define EXT4_INODE_FLAG_JOURNAL_DATA                                           \
434     0x00004000                            /* File data should be journaled */
435 #define EXT4_INODE_FLAG_NOTAIL 0x00008000 /* File tail should not be merged */
436 #define EXT4_INODE_FLAG_DIRSYNC                                                \
437     0x00010000 /* Dirsync behaviour (directories only) */
438 #define EXT4_INODE_FLAG_TOPDIR 0x00020000    /* Top of directory hierarchies */
439 #define EXT4_INODE_FLAG_HUGE_FILE 0x00040000 /* Set to each huge file */
440 #define EXT4_INODE_FLAG_EXTENTS 0x00080000   /* Inode uses extents */
441 #define EXT4_INODE_FLAG_EA_INODE 0x00200000  /* Inode used for large EA */
442 #define EXT4_INODE_FLAG_EOFBLOCKS 0x00400000 /* Blocks allocated beyond EOF */
443 #define EXT4_INODE_FLAG_RESERVED 0x80000000  /* reserved for ext4 lib */
444
445 #define EXT4_INODE_ROOT_INDEX 2
446
447 struct ext4_inode_ref {
448     struct ext4_block block;
449     struct ext4_inode *inode;
450     struct ext4_fs *fs;
451     uint32_t index;
452     bool dirty;
453 };
454
455 #define EXT4_DIRECTORY_FILENAME_LEN 255
456
457 #define EXT4_DIRECTORY_FILETYPE_UNKNOWN 0
458 #define EXT4_DIRECTORY_FILETYPE_REG_FILE 1
459 #define EXT4_DIRECTORY_FILETYPE_DIR 2
460 #define EXT4_DIRECTORY_FILETYPE_CHRDEV 3
461 #define EXT4_DIRECTORY_FILETYPE_BLKDEV 4
462 #define EXT4_DIRECTORY_FILETYPE_FIFO 5
463 #define EXT4_DIRECTORY_FILETYPE_SOCK 6
464 #define EXT4_DIRECTORY_FILETYPE_SYMLINK 7
465
466 union ext4_directory_entry_ll_internal {
467     uint8_t name_length_high; /* Higher 8 bits of name length */
468     uint8_t inode_type;       /* Type of referenced inode (in rev >= 0.5) */
469 } __attribute__((packed));
470
471 /**
472  * Linked list directory entry structure
473  */
474 struct ext4_directory_entry_ll {
475     uint32_t inode;        /* I-node for the entry */
476     uint16_t entry_length; /* Distance to the next directory entry */
477     uint8_t name_length;   /* Lower 8 bits of name length */
478
479     union ext4_directory_entry_ll_internal in;
480
481     uint8_t name[EXT4_DIRECTORY_FILENAME_LEN]; /* Entry name */
482 } __attribute__((packed));
483
484 struct ext4_directory_iterator {
485     struct ext4_inode_ref *inode_ref;
486     struct ext4_block current_block;
487     uint64_t current_offset;
488     struct ext4_directory_entry_ll *current;
489 };
490
491 struct ext4_directory_search_result {
492     struct ext4_block block;
493     struct ext4_directory_entry_ll *dentry;
494 };
495
496 /* Structures for indexed directory */
497
498 struct ext4_directory_dx_countlimit {
499     uint16_t limit;
500     uint16_t count;
501 };
502
503 struct ext4_directory_dx_dot_entry {
504     uint32_t inode;
505     uint16_t entry_length;
506     uint8_t name_length;
507     uint8_t inode_type;
508     uint8_t name[4];
509 };
510
511 struct ext4_directory_dx_root_info {
512     uint32_t reserved_zero;
513     uint8_t hash_version;
514     uint8_t info_length;
515     uint8_t indirect_levels;
516     uint8_t unused_flags;
517 };
518
519 struct ext4_directory_dx_entry {
520     uint32_t hash;
521     uint32_t block;
522 };
523
524 struct ext4_directory_dx_root {
525     struct ext4_directory_dx_dot_entry dots[2];
526     struct ext4_directory_dx_root_info info;
527     struct ext4_directory_dx_entry entries[];
528 };
529
530 struct ext4_fake_directory_entry {
531     uint32_t inode;
532     uint16_t entry_length;
533     uint8_t name_length;
534     uint8_t inode_type;
535 };
536
537 struct ext4_directory_dx_node {
538     struct ext4_fake_directory_entry fake;
539     struct ext4_directory_dx_entry entries[];
540 };
541
542 struct ext4_directory_dx_block {
543     struct ext4_block block;
544     struct ext4_directory_dx_entry *entries;
545     struct ext4_directory_dx_entry *position;
546 };
547
548 #define EXT4_ERR_BAD_DX_DIR (-25000)
549
550 #define EXT4_LINK_MAX 65000
551
552 /*
553  * This is the extent on-disk structure.
554  * It's used at the bottom of the tree.
555  */
556 struct ext4_extent {
557     uint32_t first_block; /* First logical block extent covers */
558     uint16_t block_count; /* Number of blocks covered by extent */
559     uint16_t start_hi;    /* High 16 bits of physical block */
560     uint32_t start_lo;    /* Low 32 bits of physical block */
561 };
562
563 /*
564  * This is index on-disk structure.
565  * It's used at all the levels except the bottom.
566  */
567 struct ext4_extent_index {
568     uint32_t first_block; /* Index covers logical blocks from 'block' */
569
570     /**
571      * Pointer to the physical block of the next
572      * level. leaf or next index could be there
573      * high 16 bits of physical block
574      */
575     uint32_t leaf_lo;
576     uint16_t leaf_hi;
577     uint16_t padding;
578 };
579
580 /*
581  * Each block (leaves and indexes), even inode-stored has header.
582  */
583 struct ext4_extent_header {
584     uint16_t magic;
585     uint16_t entries_count;     /* Number of valid entries */
586     uint16_t max_entries_count; /* Capacity of store in entries */
587     uint16_t depth;             /* Has tree real underlying blocks? */
588     uint32_t generation;        /* generation of the tree */
589 };
590
591 struct ext4_extent_path {
592     struct ext4_block block;
593     uint16_t depth;
594     struct ext4_extent_header *header;
595     struct ext4_extent_index *index;
596     struct ext4_extent *extent;
597 };
598
599 #define EXT4_EXTENT_MAGIC 0xF30A
600
601 #define EXT4_EXTENT_FIRST(header)                                              \
602     ((struct ext4_extent *)(((char *)(header)) +                               \
603                             sizeof(struct ext4_extent_header)))
604
605 #define EXT4_EXTENT_FIRST_INDEX(header)                                        \
606     ((struct ext4_extent_index *)(((char *)(header)) +                         \
607                                   sizeof(struct ext4_extent_header)))
608
609 /* EXT3 HTree directory indexing */
610 #define EXT2_HTREE_LEGACY 0
611 #define EXT2_HTREE_HALF_MD4 1
612 #define EXT2_HTREE_TEA 2
613 #define EXT2_HTREE_LEGACY_UNSIGNED 3
614 #define EXT2_HTREE_HALF_MD4_UNSIGNED 4
615 #define EXT2_HTREE_TEA_UNSIGNED 5
616
617 #define EXT2_HTREE_EOF 0x7FFFFFFFUL
618
619 struct ext4_hash_info {
620     uint32_t hash;
621     uint32_t minor_hash;
622     uint32_t hash_version;
623     const uint32_t *seed;
624 };
625
626 /*****************************************************************************/
627
628 #ifdef CONFIG_BIG_ENDIAN
629 static inline uint64_t to_le64(uint64_t n)
630 {
631     return ((n & 0xff) << 56) | ((n & 0xff00) << 40) | ((n & 0xff0000) << 24) |
632            ((n & 0xff000000LL) << 8) | ((n & 0xff00000000LL) >> 8) |
633            ((n & 0xff0000000000LL) >> 24) | ((n & 0xff000000000000LL) >> 40) |
634            ((n & 0xff00000000000000LL) >> 56);
635 }
636
637 static inline uint32_t to_le32(uint32_t n)
638 {
639     return ((n & 0xff) << 24) | ((n & 0xff00) << 8) | ((n & 0xff0000) >> 8) |
640            ((n & 0xff000000) >> 24);
641 }
642
643 static inline uint16_t to_le16(uint16_t n)
644 {
645     return ((n & 0xff) << 8) | ((n & 0xff00) >> 8);
646 }
647
648 #else
649 #define to_le64(_n) _n
650 #define to_le32(_n) _n
651 #define to_le16(_n) _n
652 #endif
653
654 /****************************Access macros to ext4 structures*****************/
655
656 #define ext4_get32(s, f) to_le32((s)->f)
657 #define ext4_get16(s, f) to_le16((s)->f)
658 #define ext4_get8(s, f) (s)->f
659
660 #define ext4_set32(s, f, v)                                                    \
661     do {                                                                       \
662         (s)->f = to_le32(v);                                                   \
663     } while (0)
664 #define ext4_set16(s, f, v)                                                    \
665     do {                                                                       \
666         (s)->f = to_le16(v);                                                   \
667     } while (0)
668 #define ext4_set8                                                              \
669     (s, f, v) do { (s)->f = (v); }                                             \
670     while (0)
671
672 #endif /* EXT4_TYPES_H_ */
673
674 /**
675  * @}
676  */