Update supported features
[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 /*
52  * Structure of the super block
53  */
54 struct ext4_sblock {
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_frag_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;                    /* Behaviour 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 */
80
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 */
92
93     /*
94      * Performance hints. Directory preallocation should only
95      * happen if the EXT4_FEATURE_COMPAT_DIR_PREALLOC flag is on.
96      */
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 */
100
101     /*
102      * Journaling support valid if EXT4_FEATURE_COMPAT_HAS_JOURNAL set.
103      */
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 */
116
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 */
134     uint64_t snapshot_r_blocks_count;   /* Reserved blocks for active snapshot's future use */
135     uint32_t snapshot_list;             /* I-node number of the head of the on-disk snapshot list */
136     uint32_t error_count;               /* Number of file system errors */
137     uint32_t first_error_time;          /* First time an error happened */
138     uint32_t first_error_ino;           /* I-node involved in first error */
139     uint64_t first_error_block;         /* Block involved of first error */
140     uint8_t first_error_func[32];       /* Function where the error happened */
141     uint32_t first_error_line;          /* Line number where error happened */
142     uint32_t last_error_time;           /* Most recent time of an error */
143     uint32_t last_error_ino;            /* I-node involved in last error */
144     uint32_t last_error_line;           /* Line number where error happened */
145     uint64_t last_error_block;          /* Block involved of last error */
146     uint8_t last_error_func[32];        /* Function where the error happened */
147     uint8_t mount_opts[64];
148     uint32_t padding[112];              /* Padding to the end of the block */
149 } __attribute__((packed));
150
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  /* Signed dirhash in use */
163 #define EXT4_SUPERBLOCK_FLAGS_UNSIGNED_HASH  0x0002  /* Unsigned dirhash in use */
164 #define EXT4_SUPERBLOCK_FLAGS_TEST_FILESYS   0x0004  /* to test development code */
165
166 /*
167  * Filesystem states
168  */
169 #define EXT4_SUPERBLOCK_STATE_VALID_FS   0x0001  /* Unmounted cleanly */
170 #define EXT4_SUPERBLOCK_STATE_ERROR_FS   0x0002  /* Errors detected */
171 #define EXT4_SUPERBLOCK_STATE_ORPHAN_FS  0x0004  /* Orphans being recovered */
172
173 /*
174  * Behaviour when errors detected
175  */
176 #define EXT4_SUPERBLOCK_ERRORS_CONTINUE  1  /* Continue execution */
177 #define EXT4_SUPERBLOCK_ERRORS_RO        2  /* Remount fs read-only */
178 #define EXT4_SUPERBLOCK_ERRORS_PANIC     3  /* Panic */
179 #define EXT4_SUPERBLOCK_ERRORS_DEFAULT   EXT4_ERRORS_CONTINUE
180
181 /*
182  * Compatible features
183  */
184 #define EXT4_FEATURE_COMPAT_DIR_PREALLOC   0x0001
185 #define EXT4_FEATURE_COMPAT_IMAGIC_INODES  0x0002
186 #define EXT4_FEATURE_COMPAT_HAS_JOURNAL    0x0004
187 #define EXT4_FEATURE_COMPAT_EXT_ATTR       0x0008
188 #define EXT4_FEATURE_COMPAT_RESIZE_INODE   0x0010
189 #define EXT4_FEATURE_COMPAT_DIR_INDEX      0x0020
190
191
192 /*
193  * Read-only compatible features
194  */
195 #define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER  0x0001
196 #define EXT4_FEATURE_RO_COMPAT_LARGE_FILE    0x0002
197 #define EXT4_FEATURE_RO_COMPAT_BTREE_DIR     0x0004
198 #define EXT4_FEATURE_RO_COMPAT_HUGE_FILE     0x0008
199 #define EXT4_FEATURE_RO_COMPAT_GDT_CSUM      0x0010
200 #define EXT4_FEATURE_RO_COMPAT_DIR_NLINK     0x0020
201 #define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE   0x0040
202 #define EXT4_FEATURE_RO_COMPAT_QUOTA         0x0100
203 #define EXT4_FEATURE_RO_COMPAT_BIGALLOC      0x0200
204 #define EXT4_FEATURE_RO_COMPAT_METADATA_CSUM 0x0400
205
206 /*
207  * Incompatible features
208  */
209 #define EXT4_FEATURE_INCOMPAT_COMPRESSION  0x0001
210 #define EXT4_FEATURE_INCOMPAT_FILETYPE     0x0002
211 #define EXT4_FEATURE_INCOMPAT_RECOVER      0x0004  /* Needs recovery */
212 #define EXT4_FEATURE_INCOMPAT_JOURNAL_DEV  0x0008  /* Journal device */
213 #define EXT4_FEATURE_INCOMPAT_META_BG      0x0010
214 #define EXT4_FEATURE_INCOMPAT_EXTENTS      0x0040  /* extents support */
215 #define EXT4_FEATURE_INCOMPAT_64BIT        0x0080
216 #define EXT4_FEATURE_INCOMPAT_MMP          0x0100
217 #define EXT4_FEATURE_INCOMPAT_FLEX_BG      0x0200
218 #define EXT4_FEATURE_INCOMPAT_EA_INODE     0x0400  /* EA in inode */
219 #define EXT4_FEATURE_INCOMPAT_DIRDATA      0x1000  /* data in dirent */
220 #define EXT4_FEATURE_INCOMPAT_BG_USE_META_CSUM  0x2000 /* use crc32c for bg */
221 #define EXT4_FEATURE_INCOMPAT_LARGEDIR          0x4000 /* >2GB or 3-lvl htree */
222 #define EXT4_FEATURE_INCOMPAT_INLINE_DATA       0x8000 /* data in inode */
223
224
225 /*
226  * EXT2 supported feature set
227  */
228 #define EXT2_FEATURE_COMPAT_SUPP    0x0000
229
230 #define EXT2_FEATURE_INCOMPAT_SUPP                    \
231             (EXT4_FEATURE_INCOMPAT_FILETYPE         | \
232              EXT4_FEATURE_INCOMPAT_META_BG)
233
234 #define EXT2_FEATURE_RO_COMPAT_SUPP                   \
235             (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER    | \
236              EXT4_FEATURE_RO_COMPAT_LARGE_FILE      | \
237              EXT4_FEATURE_RO_COMPAT_BTREE_DIR)
238
239 /*
240  * EXT3 supported feature set
241  */
242 #define EXT3_FEATURE_COMPAT_SUPP                      \
243             (EXT4_FEATURE_COMPAT_DIR_INDEX)
244
245 #define EXT3_FEATURE_INCOMPAT_SUPP                    \
246             (EXT4_FEATURE_INCOMPAT_FILETYPE         | \
247              EXT4_FEATURE_INCOMPAT_META_BG)
248
249 #define EXT3_FEATURE_RO_COMPAT_SUPP                   \
250             (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER    | \
251              EXT4_FEATURE_RO_COMPAT_LARGE_FILE      | \
252              EXT4_FEATURE_RO_COMPAT_BTREE_DIR)
253
254 /*
255  * EXT4 supported feature set
256  */
257 #define EXT4_FEATURE_COMPAT_SUPP                      \
258             (EXT4_FEATURE_COMPAT_DIR_INDEX)
259
260 #define EXT4_FEATURE_INCOMPAT_SUPP                    \
261             (EXT4_FEATURE_INCOMPAT_FILETYPE         | \
262             EXT4_FEATURE_INCOMPAT_META_BG           | \
263             EXT4_FEATURE_INCOMPAT_EXTENTS           | \
264             EXT4_FEATURE_INCOMPAT_64BIT)
265
266 #define EXT4_FEATURE_RO_COMPAT_SUPP                   \
267             (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER    | \
268             EXT4_FEATURE_RO_COMPAT_LARGE_FILE       | \
269             EXT4_FEATURE_RO_COMPAT_GDT_CSUM         | \
270             EXT4_FEATURE_RO_COMPAT_DIR_NLINK        | \
271             EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE      | \
272             EXT4_FEATURE_RO_COMPAT_BTREE_DIR        | \
273             EXT4_FEATURE_RO_COMPAT_HUGE_FILE)
274
275
276 /*Ignored features:
277  * RECOVER - journaling in lwext4 is not supported
278  *           (probably won,t be ever...)
279  * MMP - multi mout protection (impossible scenario)
280  * */
281 #define FEATURE_INCOMPAT_IGNORED                      \
282         EXT4_FEATURE_INCOMPAT_RECOVER               | \
283         EXT4_FEATURE_INCOMPAT_MMP)
284
285 #if 0
286 /*TODO: Features incompatible to implement*/
287 #define EXT4_FEATURE_INCOMPAT_SUPP
288                      EXT4_FEATURE_INCOMPAT_FLEX_BG| \
289                      EXT4_FEATURE_INCOMPAT_INLINE_DATA)
290
291 /*TODO: Features read only to implement*/
292 #define EXT4_FEATURE_RO_COMPAT_SUPP
293                      EXT4_FEATURE_RO_COMPAT_BIGALLOC |\
294                      EXT4_FEATURE_RO_COMPAT_METADATA_CSUM|\
295                      EXT4_FEATURE_RO_COMPAT_QUOTA)
296 #endif
297
298 struct ext4_fs {
299     struct ext4_blockdev*bdev;
300     struct ext4_sblock sb;
301
302     uint64_t inode_block_limits[4];
303     uint64_t inode_blocks_per_level[4];
304
305     uint32_t last_inode_bg_id;
306 };
307
308
309 #define EXT4_BLOCK_GROUP_INODE_UNINIT   0x0001  /* Inode table/bitmap not in use */
310 #define EXT4_BLOCK_GROUP_BLOCK_UNINIT   0x0002  /* Block bitmap not in use */
311 #define EXT4_BLOCK_GROUP_ITABLE_ZEROED  0x0004  /* On-disk itable initialized to zero */
312
313 /*
314  * Structure of a blocks group descriptor
315  */
316 struct ext4_bgroup {
317     uint32_t block_bitmap_lo;             /* Blocks bitmap block */
318     uint32_t inode_bitmap_lo;             /* Inodes bitmap block */
319     uint32_t inode_table_first_block_lo;  /* Inodes table block */
320     uint16_t free_blocks_count_lo;        /* Free blocks count */
321     uint16_t free_inodes_count_lo;        /* Free inodes count */
322     uint16_t used_dirs_count_lo;          /* Directories count */
323     uint16_t flags;                       /* EXT4_BG_flags (INODE_UNINIT, etc) */
324     uint32_t exclude_bitmap_lo;           /* Exclude bitmap for snapshots */
325         uint16_t block_bitmap_csum_lo;        /* crc32c(s_uuid+grp_num+bbitmap) LE */
326         uint16_t inode_bitmap_csum_lo;        /* crc32c(s_uuid+grp_num+ibitmap) LE */
327     uint16_t itable_unused_lo;            /* Unused inodes count */
328     uint16_t checksum;                    /* crc16(sb_uuid+group+desc) */
329
330     uint32_t block_bitmap_hi;             /* Blocks bitmap block MSB */
331     uint32_t inode_bitmap_hi;             /* I-nodes bitmap block MSB */
332     uint32_t inode_table_first_block_hi;  /* I-nodes table block MSB */
333     uint16_t free_blocks_count_hi;        /* Free blocks count MSB */
334     uint16_t free_inodes_count_hi;        /* Free i-nodes count MSB */
335     uint16_t used_dirs_count_hi;          /* Directories count MSB */
336     uint16_t itable_unused_hi;            /* Unused inodes count MSB */
337     uint32_t exclude_bitmap_hi;           /* Exclude bitmap block MSB */
338         uint16_t block_bitmap_csum_hi;        /* crc32c(s_uuid+grp_num+bbitmap) BE */
339         uint16_t inode_bitmap_csum_hi;        /* crc32c(s_uuid+grp_num+ibitmap) BE */
340         uint32_t reserved;                    /* Padding */
341 } ;
342
343 struct ext4_block_group_ref {
344     struct ext4_block block;
345     struct ext4_bgroup *block_group;
346     struct ext4_fs *fs;
347     uint32_t index;
348     bool dirty;
349 };
350
351 #define EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE  32
352 #define EXT4_MAX_BLOCK_GROUP_DESCRIPTOR_SIZE  64
353
354 #define EXT4_MIN_BLOCK_SIZE   1024   /* 1 KiB */
355 #define EXT4_MAX_BLOCK_SIZE   65536  /* 64 KiB */
356 #define EXT4_REV0_INODE_SIZE  128
357
358 #define EXT4_INODE_BLOCK_SIZE  512
359
360 #define EXT4_INODE_DIRECT_BLOCK_COUNT      12
361 #define EXT4_INODE_INDIRECT_BLOCK          EXT4_INODE_DIRECT_BLOCK_COUNT
362 #define EXT4_INODE_DOUBLE_INDIRECT_BLOCK   (EXT4_INODE_INDIRECT_BLOCK + 1)
363 #define EXT4_INODE_TRIPPLE_INDIRECT_BLOCK  (EXT4_INODE_DOUBLE_INDIRECT_BLOCK + 1)
364 #define EXT4_INODE_BLOCKS                  (EXT4_INODE_TRIPPLE_INDIRECT_BLOCK + 1)
365 #define EXT4_INODE_INDIRECT_BLOCK_COUNT    (EXT4_INODE_BLOCKS - EXT4_INODE_DIRECT_BLOCK_COUNT)
366
367 /*
368  * Structure of an inode on the disk
369  */
370 struct ext4_inode {
371     uint16_t mode;                       /* File mode */
372     uint16_t uid;                        /* Low 16 bits of owner uid */
373     uint32_t size_lo;                    /* Size in bytes */
374     uint32_t access_time;                /* Access time */
375     uint32_t change_inode_time;          /* I-node change time */
376     uint32_t modification_time;          /* Modification time */
377     uint32_t deletion_time;              /* Deletion time */
378     uint16_t gid;                        /* Low 16 bits of group id */
379     uint16_t links_count;                /* Links count */
380     uint32_t blocks_count_lo;            /* Blocks count */
381     uint32_t flags;                      /* File flags */
382     uint32_t unused_osd1;                /* OS dependent - not used in HelenOS */
383     uint32_t blocks[EXT4_INODE_BLOCKS];  /* Pointers to blocks */
384     uint32_t generation;                 /* File version (for NFS) */
385     uint32_t file_acl_lo;                /* File ACL */
386     uint32_t size_hi;
387     uint32_t obso_faddr;                 /* Obsoleted fragment address */
388
389     union {
390         struct {
391             uint16_t blocks_high;
392             uint16_t file_acl_high;
393             uint16_t uid_high;
394             uint16_t gid_high;
395             uint32_t reserved2;
396         } linux2;
397         struct {
398             uint16_t reserved1;
399             uint16_t mode_high;
400             uint16_t uid_high;
401             uint16_t gid_high;
402             uint32_t author;
403         } hurd2;
404     } __attribute__ ((packed)) osd2;
405
406     uint16_t extra_isize;
407     uint16_t pad1;
408     uint32_t ctime_extra;   /* Extra change time (nsec << 2 | epoch) */
409     uint32_t mtime_extra;   /* Extra Modification time (nsec << 2 | epoch) */
410     uint32_t atime_extra;   /* Extra Access time (nsec << 2 | epoch) */
411     uint32_t crtime;        /* File creation time */
412     uint32_t crtime_extra;  /* Extra file creation time (nsec << 2 | epoch) */
413     uint32_t version_hi;    /* High 32 bits for 64-bit version */
414 } __attribute__ ((packed)) ;
415
416 #define EXT4_INODE_MODE_FIFO       0x1000
417 #define EXT4_INODE_MODE_CHARDEV    0x2000
418 #define EXT4_INODE_MODE_DIRECTORY  0x4000
419 #define EXT4_INODE_MODE_BLOCKDEV   0x6000
420 #define EXT4_INODE_MODE_FILE       0x8000
421 #define EXT4_INODE_MODE_SOFTLINK   0xA000
422 #define EXT4_INODE_MODE_SOCKET     0xC000
423 #define EXT4_INODE_MODE_TYPE_MASK  0xF000
424
425 /*
426  * Inode flags
427  */
428 #define EXT4_INODE_FLAG_SECRM      0x00000001  /* Secure deletion */
429 #define EXT4_INODE_FLAG_UNRM       0x00000002  /* Undelete */
430 #define EXT4_INODE_FLAG_COMPR      0x00000004  /* Compress file */
431 #define EXT4_INODE_FLAG_SYNC       0x00000008  /* Synchronous updates */
432 #define EXT4_INODE_FLAG_IMMUTABLE  0x00000010  /* Immutable file */
433 #define EXT4_INODE_FLAG_APPEND     0x00000020  /* writes to file may only append */
434 #define EXT4_INODE_FLAG_NODUMP     0x00000040  /* do not dump file */
435 #define EXT4_INODE_FLAG_NOATIME    0x00000080  /* do not update atime */
436
437 /* Compression flags */
438 #define EXT4_INODE_FLAG_DIRTY     0x00000100
439 #define EXT4_INODE_FLAG_COMPRBLK  0x00000200  /* One or more compressed clusters */
440 #define EXT4_INODE_FLAG_NOCOMPR   0x00000400  /* Don't compress */
441 #define EXT4_INODE_FLAG_ECOMPR    0x00000800  /* Compression error */
442
443 #define EXT4_INODE_FLAG_INDEX         0x00001000  /* hash-indexed directory */
444 #define EXT4_INODE_FLAG_IMAGIC        0x00002000  /* AFS directory */
445 #define EXT4_INODE_FLAG_JOURNAL_DATA  0x00004000  /* File data should be journaled */
446 #define EXT4_INODE_FLAG_NOTAIL        0x00008000  /* File tail should not be merged */
447 #define EXT4_INODE_FLAG_DIRSYNC       0x00010000  /* Dirsync behaviour (directories only) */
448 #define EXT4_INODE_FLAG_TOPDIR        0x00020000  /* Top of directory hierarchies */
449 #define EXT4_INODE_FLAG_HUGE_FILE     0x00040000  /* Set to each huge file */
450 #define EXT4_INODE_FLAG_EXTENTS       0x00080000  /* Inode uses extents */
451 #define EXT4_INODE_FLAG_EA_INODE      0x00200000  /* Inode used for large EA */
452 #define EXT4_INODE_FLAG_EOFBLOCKS     0x00400000  /* Blocks allocated beyond EOF */
453 #define EXT4_INODE_FLAG_RESERVED      0x80000000  /* reserved for ext4 lib */
454
455 #define EXT4_INODE_ROOT_INDEX  2
456
457 struct ext4_inode_ref {
458     struct ext4_block  block;
459     struct ext4_inode *inode;
460     struct ext4_fs  *fs;
461     uint32_t index;
462     bool dirty;
463 } ;
464
465
466 #define EXT4_DIRECTORY_FILENAME_LEN  255
467
468 #define EXT4_DIRECTORY_FILETYPE_UNKNOWN   0
469 #define EXT4_DIRECTORY_FILETYPE_REG_FILE  1
470 #define EXT4_DIRECTORY_FILETYPE_DIR       2
471 #define EXT4_DIRECTORY_FILETYPE_CHRDEV    3
472 #define EXT4_DIRECTORY_FILETYPE_BLKDEV    4
473 #define EXT4_DIRECTORY_FILETYPE_FIFO      5
474 #define EXT4_DIRECTORY_FILETYPE_SOCK      6
475 #define EXT4_DIRECTORY_FILETYPE_SYMLINK   7
476
477 union ext4_directory_entry_ll_internal{
478     uint8_t name_length_high;  /* Higher 8 bits of name length */
479     uint8_t inode_type;        /* Type of referenced inode (in rev >= 0.5) */
480 } __attribute__ ((packed));
481
482 /**
483  * Linked list directory entry structure
484  */
485 struct ext4_directory_entry_ll {
486     uint32_t inode;         /* I-node for the entry */
487     uint16_t entry_length;  /* Distance to the next directory entry */
488     uint8_t name_length;    /* Lower 8 bits of name length */
489
490     union ext4_directory_entry_ll_internal in;
491
492     uint8_t name[EXT4_DIRECTORY_FILENAME_LEN];  /* Entry name */
493 } __attribute__((packed)) ;
494
495 struct ext4_directory_iterator {
496     struct ext4_inode_ref *inode_ref;
497     struct ext4_block current_block;
498     uint64_t current_offset;
499     struct ext4_directory_entry_ll  *current;
500 };
501
502 struct ext4_directory_search_result {
503     struct ext4_block block;
504     struct ext4_directory_entry_ll *dentry;
505 };
506
507 /* Structures for indexed directory */
508
509 struct ext4_directory_dx_countlimit {
510     uint16_t limit;
511     uint16_t count;
512 } ;
513
514 struct ext4_directory_dx_dot_entry {
515     uint32_t inode;
516     uint16_t entry_length;
517     uint8_t name_length;
518     uint8_t inode_type;
519     uint8_t name[4];
520 } ;
521
522 struct ext4_directory_dx_root_info {
523     uint32_t reserved_zero;
524     uint8_t hash_version;
525     uint8_t info_length;
526     uint8_t indirect_levels;
527     uint8_t unused_flags;
528 } ;
529
530 struct ext4_directory_dx_entry {
531     uint32_t hash;
532     uint32_t block;
533 } ;
534
535 struct ext4_directory_dx_root {
536     struct ext4_directory_dx_dot_entry dots[2];
537     struct ext4_directory_dx_root_info info;
538     struct ext4_directory_dx_entry entries[];
539 };
540
541 struct ext4_fake_directory_entry {
542     uint32_t inode;
543     uint16_t entry_length;
544     uint8_t name_length;
545     uint8_t inode_type;
546 };
547
548 struct ext4_directory_dx_node {
549     struct ext4_fake_directory_entry fake;
550     struct ext4_directory_dx_entry entries[];
551 };
552
553 struct ext4_directory_dx_block {
554     struct ext4_block block;
555     struct ext4_directory_dx_entry *entries;
556     struct ext4_directory_dx_entry *position;
557 } ;
558
559 #define EXT4_ERR_BAD_DX_DIR       (-25000)
560
561
562 /*
563  * This is the extent on-disk structure.
564  * It's used at the bottom of the tree.
565  */
566 struct ext4_extent {
567     uint32_t first_block;  /* First logical block extent covers */
568     uint16_t block_count;  /* Number of blocks covered by extent */
569     uint16_t start_hi;     /* High 16 bits of physical block */
570     uint32_t start_lo;     /* Low 32 bits of physical block */
571 } ;
572
573 /*
574  * This is index on-disk structure.
575  * It's used at all the levels except the bottom.
576  */
577 struct ext4_extent_index {
578     uint32_t first_block;  /* Index covers logical blocks from 'block' */
579
580     /**
581      * Pointer to the physical block of the next
582      * level. leaf or next index could be there
583      * high 16 bits of physical block
584      */
585     uint32_t leaf_lo;
586     uint16_t leaf_hi;
587     uint16_t padding;
588 } ;
589
590 /*
591  * Each block (leaves and indexes), even inode-stored has header.
592  */
593 struct ext4_extent_header {
594     uint16_t magic;
595     uint16_t entries_count;      /* Number of valid entries */
596     uint16_t max_entries_count;  /* Capacity of store in entries */
597     uint16_t depth;              /* Has tree real underlying blocks? */
598     uint32_t generation;         /* generation of the tree */
599 } ;
600
601 struct ext4_extent_path {
602     struct ext4_block block;
603     uint16_t depth;
604     struct ext4_extent_header *header;
605     struct ext4_extent_index *index;
606     struct ext4_extent *extent;
607 } ;
608
609 #define EXT4_EXTENT_MAGIC  0xF30A
610
611 #define EXT4_EXTENT_FIRST(header) \
612         ((struct ext4_extent *) (((char *) (header)) + sizeof(struct ext4_extent_header)))
613
614 #define EXT4_EXTENT_FIRST_INDEX(header) \
615         ((struct ext4_extent_index *) (((char *) (header)) + sizeof(struct ext4_extent_header)))
616
617
618 /* EXT3 HTree directory indexing */
619 #define EXT2_HTREE_LEGACY                   0
620 #define EXT2_HTREE_HALF_MD4                 1
621 #define EXT2_HTREE_TEA                      2
622 #define EXT2_HTREE_LEGACY_UNSIGNED          3
623 #define EXT2_HTREE_HALF_MD4_UNSIGNED        4
624 #define EXT2_HTREE_TEA_UNSIGNED             5
625
626 #define EXT2_HTREE_EOF                      0x7FFFFFFFUL
627
628
629 struct ext4_hash_info {
630     uint32_t hash;
631     uint32_t minor_hash;
632     uint32_t hash_version;
633     const uint32_t *seed;
634 };
635
636 /*****************************************************************************/
637
638
639 #ifdef CONFIG_BIG_ENDIAN
640 static inline uint64_t to_le64(uint64_t n)
641 {
642     return  ((n & 0xff) << 56) |
643             ((n & 0xff00) << 40) |
644             ((n & 0xff0000) << 24) |
645             ((n & 0xff000000LL) << 8) |
646             ((n & 0xff00000000LL) >> 8) |
647             ((n & 0xff0000000000LL) >> 24) |
648             ((n & 0xff000000000000LL) >> 40) |
649             ((n & 0xff00000000000000LL) >> 56);
650 }
651
652 static inline uint32_t to_le32(uint32_t n)
653 {
654     return  ((n & 0xff) << 24) |
655             ((n & 0xff00) << 8) |
656             ((n & 0xff0000) >> 8) |
657             ((n & 0xff000000) >> 24);
658 }
659
660 static inline uint16_t to_le16(uint16_t n)
661 {
662     return  ((n & 0xff) << 8) |
663             ((n & 0xff00) >> 8);
664 }
665
666
667 #else
668 #define to_le64(_n) _n
669 #define to_le32(_n) _n
670 #define to_le16(_n) _n
671 #endif
672
673 /****************************Access macros to ext4 structures*****************/
674
675 #define ext4_get32(s, f)        to_le32((s)->f)
676 #define ext4_get16(s, f)        to_le16((s)->f)
677 #define ext4_get8(s, f)         (s)->f
678
679
680 #define ext4_set32(s, f, v)     do { (s)->f = to_le32(v); }while(0)
681 #define ext4_set16(s, f, v)     do { (s)->f = to_le16(v); }while(0)
682 #define ext4_set8 (s, f, v)     do { (s)->f = (v);        }while(0)
683
684 #endif /* EXT4_TYPES_H_ */
685
686 /**
687  * @}
688  */