Add mkfs to debug module
[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 #include "tree.h"
48
49 #include <stdint.h>
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_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 */
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
135             snapshot_r_blocks_count; /* Reserved blocks for active snapshot's
136                                         future use */
137         uint32_t
138             snapshot_list; /* I-node number of the head of the on-disk snapshot
139                               list */
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));
154
155 #define EXT4_SUPERBLOCK_MAGIC 0xEF53
156 #define EXT4_SUPERBLOCK_SIZE 1024
157 #define EXT4_SUPERBLOCK_OFFSET 1024
158
159 #define EXT4_SUPERBLOCK_OS_LINUX 0
160 #define EXT4_SUPERBLOCK_OS_HURD 1
161
162 /*
163  * Misc. filesystem flags
164  */
165 #define EXT4_SUPERBLOCK_FLAGS_SIGNED_HASH 0x0001
166 #define EXT4_SUPERBLOCK_FLAGS_UNSIGNED_HASH 0x0002
167 #define EXT4_SUPERBLOCK_FLAGS_TEST_FILESYS 0x0004
168 /*
169  * Filesystem states
170  */
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 */
174
175 /*
176  * Behaviour when errors detected
177  */
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
182
183 /*
184  * Compatible features
185  */
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
192
193 /*
194  * Read-only compatible features
195  */
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
206
207 /*
208  * Incompatible features
209  */
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 */
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 | EXT4_FEATURE_INCOMPAT_META_BG)
232
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)
236
237 /*
238  * EXT3 supported feature set
239  */
240 #define EXT3_FEATURE_COMPAT_SUPP (EXT4_FEATURE_COMPAT_DIR_INDEX)
241
242 #define EXT3_FEATURE_INCOMPAT_SUPP                                             \
243         (EXT4_FEATURE_INCOMPAT_FILETYPE | EXT4_FEATURE_INCOMPAT_META_BG)
244
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)
248
249 /*
250  * EXT4 supported feature set
251  */
252 #define EXT4_FEATURE_COMPAT_SUPP (EXT4_FEATURE_COMPAT_DIR_INDEX)
253
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)
258
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)
265
266 /*Ignored features:
267  * RECOVER - journaling in lwext4 is not supported
268  *           (probably won't be ever...)
269  * MMP - multi-mout protection (impossible scenario)
270  * */
271 #define FEATURE_INCOMPAT_IGNORED                                               \
272         EXT4_FEATURE_INCOMPAT_RECOVER | EXT4_FEATURE_INCOMPAT_MMP
273
274 #if 0
275 /*TODO: Features incompatible to implement*/
276 #define EXT4_FEATURE_INCOMPAT_SUPP
277                      (EXT4_FEATURE_INCOMPAT_INLINE_DATA)
278
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)
284 #endif
285
286 struct ext4_fs {
287         struct ext4_blockdev *bdev;
288         struct ext4_sblock sb;
289
290         uint64_t inode_block_limits[4];
291         uint64_t inode_blocks_per_level[4];
292
293         uint32_t last_inode_bg_id;
294 };
295
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
302
303 /*
304  * Structure of a blocks group descriptor
305  */
306 struct ext4_bgroup {
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) */
319
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 */
331 };
332
333 struct ext4_block_group_ref {
334         struct ext4_block block;
335         struct ext4_bgroup *block_group;
336         struct ext4_fs *fs;
337         uint32_t index;
338         bool dirty;
339 };
340
341 #define EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE 32
342 #define EXT4_MAX_BLOCK_GROUP_DESCRIPTOR_SIZE 64
343
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
347
348 #define EXT4_INODE_BLOCK_SIZE 512
349
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)
357
358 /*
359  * Structure of an inode on the disk
360  */
361 struct ext4_inode {
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 */
377         uint32_t size_hi;
378         uint32_t obso_faddr; /* Obsoleted fragment address */
379
380         union {
381                 struct {
382                         uint16_t blocks_high;
383                         uint16_t file_acl_high;
384                         uint16_t uid_high;
385                         uint16_t gid_high;
386                         uint32_t reserved2;
387                 } linux2;
388                 struct {
389                         uint16_t reserved1;
390                         uint16_t mode_high;
391                         uint16_t uid_high;
392                         uint16_t gid_high;
393                         uint32_t author;
394                 } hurd2;
395         } __attribute__((packed)) osd2;
396
397         uint16_t extra_isize;
398         uint16_t pad1;
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 */
403         uint32_t
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));
407
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
416
417 /*
418  * Inode flags
419  */
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 */
428
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 */
435
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 */
449
450 #define EXT4_INODE_ROOT_INDEX 2
451
452 struct ext4_inode_ref {
453         struct ext4_block block;
454         struct ext4_inode *inode;
455         struct ext4_fs *fs;
456         uint32_t index;
457         bool dirty;
458 };
459
460 #define EXT4_DIRECTORY_FILENAME_LEN 255
461
462 /**@brief   Directory entry types. */
463 enum { EXT4_DIRENTRY_UNKNOWN = 0,
464        EXT4_DIRENTRY_REG_FILE,
465        EXT4_DIRENTRY_DIR,
466        EXT4_DIRENTRY_CHRDEV,
467        EXT4_DIRENTRY_BLKDEV,
468        EXT4_DIRENTRY_FIFO,
469        EXT4_DIRENTRY_SOCK,
470        EXT4_DIRENTRY_SYMLINK };
471
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));
476
477 /**
478  * Linked list directory entry structure
479  */
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 */
484
485         union ext4_directory_entry_ll_internal in;
486
487         uint8_t name[EXT4_DIRECTORY_FILENAME_LEN]; /* Entry name */
488 } __attribute__((packed));
489
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;
495 };
496
497 struct ext4_directory_search_result {
498         struct ext4_block block;
499         struct ext4_directory_entry_ll *dentry;
500 };
501
502 /* Structures for indexed directory */
503
504 struct ext4_directory_dx_countlimit {
505         uint16_t limit;
506         uint16_t count;
507 };
508
509 struct ext4_directory_dx_dot_entry {
510         uint32_t inode;
511         uint16_t entry_length;
512         uint8_t name_length;
513         uint8_t inode_type;
514         uint8_t name[4];
515 };
516
517 struct ext4_directory_dx_root_info {
518         uint32_t reserved_zero;
519         uint8_t hash_version;
520         uint8_t info_length;
521         uint8_t indirect_levels;
522         uint8_t unused_flags;
523 };
524
525 struct ext4_directory_dx_entry {
526         uint32_t hash;
527         uint32_t block;
528 };
529
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[];
534 };
535
536 struct ext4_fake_directory_entry {
537         uint32_t inode;
538         uint16_t entry_length;
539         uint8_t name_length;
540         uint8_t inode_type;
541 };
542
543 struct ext4_directory_dx_node {
544         struct ext4_fake_directory_entry fake;
545         struct ext4_directory_dx_entry entries[];
546 };
547
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;
552 };
553
554 #define EXT4_ERR_BAD_DX_DIR (-25000)
555
556 #define EXT4_LINK_MAX 65000
557
558 #define EXT4_EXT_UNWRITTEN_MASK (1L << 15)
559
560 #define EXT4_EXT_MAX_LEN_WRITTEN (1L << 15)
561 #define EXT4_EXT_MAX_LEN_UNWRITTEN \
562         (EXT4_EXT_MAX_LEN_WRITTEN - 1)
563
564 #define EXT4_EXT_GET_LEN(ex) to_le16((ex)->block_count)
565 #define EXT4_EXT_GET_LEN_UNWRITTEN(ex) \
566         (EXT4_EXT_GET_LEN(ex) &= ~(EXT4_EXT_UNWRITTEN_MASK))
567 #define EXT4_EXT_SET_LEN(ex, count) \
568         ((ex)->block_count = to_le16(count))
569
570 #define EXT4_EXT_IS_UNWRITTEN(ex) \
571         (EXT4_EXT_GET_LEN(ex) > EXT4_EXT_MAX_LEN_WRITTEN)
572 #define EXT4_EXT_SET_UNWRITTEN(ex) \
573         ((ex)->block_count |= to_le16(EXT4_EXT_UNWRITTEN_MASK))
574 #define EXT4_EXT_SET_WRITTEN(ex) \
575         ((ex)->block_count &= ~(to_le16(EXT4_EXT_UNWRITTEN_MASK)))
576
577 /*
578  * This is the extent on-disk structure.
579  * It's used at the bottom of the tree.
580  */
581 struct ext4_extent {
582         uint32_t first_block; /* First logical block extent covers */
583         uint16_t block_count; /* Number of blocks covered by extent */
584         uint16_t start_hi;    /* High 16 bits of physical block */
585         uint32_t start_lo;    /* Low 32 bits of physical block */
586 };
587
588 /*
589  * This is index on-disk structure.
590  * It's used at all the levels except the bottom.
591  */
592 struct ext4_extent_index {
593         uint32_t first_block; /* Index covers logical blocks from 'block' */
594
595         /**
596          * Pointer to the physical block of the next
597          * level. leaf or next index could be there
598          * high 16 bits of physical block
599          */
600         uint32_t leaf_lo;
601         uint16_t leaf_hi;
602         uint16_t padding;
603 };
604
605 /*
606  * Each block (leaves and indexes), even inode-stored has header.
607  */
608 struct ext4_extent_header {
609         uint16_t magic;
610         uint16_t entries_count;     /* Number of valid entries */
611         uint16_t max_entries_count; /* Capacity of store in entries */
612         uint16_t depth;             /* Has tree real underlying blocks? */
613         uint32_t generation;    /* generation of the tree */
614 };
615
616 struct ext4_extent_path {
617         struct ext4_block block;
618         uint16_t depth;
619         struct ext4_extent_header *header;
620         struct ext4_extent_index *index;
621         struct ext4_extent *extent;
622 };
623
624 #define EXT4_EXTENT_MAGIC 0xF30A
625
626 #define EXT4_EXTENT_FIRST(header)                                              \
627         ((struct ext4_extent *)(((char *)(header)) +                           \
628                                 sizeof(struct ext4_extent_header)))
629
630 #define EXT4_EXTENT_FIRST_INDEX(header)                                        \
631         ((struct ext4_extent_index *)(((char *)(header)) +                     \
632                                       sizeof(struct ext4_extent_header)))
633
634 /* EXT3 HTree directory indexing */
635 #define EXT2_HTREE_LEGACY 0
636 #define EXT2_HTREE_HALF_MD4 1
637 #define EXT2_HTREE_TEA 2
638 #define EXT2_HTREE_LEGACY_UNSIGNED 3
639 #define EXT2_HTREE_HALF_MD4_UNSIGNED 4
640 #define EXT2_HTREE_TEA_UNSIGNED 5
641
642 #define EXT2_HTREE_EOF 0x7FFFFFFFUL
643
644 struct ext4_hash_info {
645         uint32_t hash;
646         uint32_t minor_hash;
647         uint32_t hash_version;
648         const uint32_t *seed;
649 };
650
651 /* Extended Attribute(EA) */
652
653 /* Magic value in attribute blocks */
654 #define EXT4_XATTR_MAGIC                0xEA020000
655
656 /* Maximum number of references to one attribute block */
657 #define EXT4_XATTR_REFCOUNT_MAX         1024
658
659 /* Name indexes */
660 #define EXT4_XATTR_INDEX_USER                   1
661 #define EXT4_XATTR_INDEX_POSIX_ACL_ACCESS       2
662 #define EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT      3
663 #define EXT4_XATTR_INDEX_TRUSTED                4
664 #define EXT4_XATTR_INDEX_LUSTRE                 5
665 #define EXT4_XATTR_INDEX_SECURITY               6
666 #define EXT4_XATTR_INDEX_SYSTEM                 7
667 #define EXT4_XATTR_INDEX_RICHACL                8
668 #define EXT4_XATTR_INDEX_ENCRYPTION             9
669
670 struct ext4_xattr_header {
671         uint32_t h_magic;       /* magic number for identification */
672         uint32_t h_refcount;    /* reference count */
673         uint32_t h_blocks;      /* number of disk blocks used */
674         uint32_t h_hash;                /* hash value of all attributes */
675         uint32_t h_checksum;    /* crc32c(uuid+id+xattrblock) */
676                                 /* id = inum if refcount=1, blknum otherwise */
677         uint32_t h_reserved[3]; /* zero right now */
678 } __attribute__((packed));
679
680 struct ext4_xattr_ibody_header {
681         uint32_t h_magic;       /* magic number for identification */
682 } __attribute__((packed));
683
684 struct ext4_xattr_entry {
685         uint8_t e_name_len;     /* length of name */
686         uint8_t e_name_index;   /* attribute name index */
687         uint16_t e_value_offs;  /* offset in disk block of value */
688         uint32_t e_value_block; /* disk block attribute is stored on (n/i) */
689         uint32_t e_value_size;  /* size of attribute value */
690         uint32_t e_hash;                /* hash value of name and value */
691 } __attribute__((packed));
692
693 struct ext4_xattr_item {
694         uint8_t name_index;
695         char  *name;
696         size_t name_len;
697         void  *data;
698         size_t data_size;
699
700         RB_ENTRY(ext4_xattr_item) node;
701 };
702
703 struct ext4_xattr_ref {
704         bool block_loaded;
705         struct ext4_block block;
706         struct ext4_inode_ref *inode_ref;
707         bool   dirty;
708         size_t ea_size;
709         struct ext4_fs *fs;
710
711         void *iter_arg;
712         struct ext4_xattr_item *iter_from;
713
714         RB_HEAD(ext4_xattr_tree,
715                 ext4_xattr_item) root;
716 };
717
718 #define EXT4_XATTR_ITERATE_CONT 0
719 #define EXT4_XATTR_ITERATE_STOP 1
720 #define EXT4_XATTR_ITERATE_PAUSE 2
721
722 #define EXT4_GOOD_OLD_INODE_SIZE        128
723
724 #define EXT4_XATTR_PAD_BITS             2
725 #define EXT4_XATTR_PAD          (1<<EXT4_XATTR_PAD_BITS)
726 #define EXT4_XATTR_ROUND                (EXT4_XATTR_PAD-1)
727 #define EXT4_XATTR_LEN(name_len) \
728         (((name_len) + EXT4_XATTR_ROUND + \
729         sizeof(struct ext4_xattr_entry)) & ~EXT4_XATTR_ROUND)
730 #define EXT4_XATTR_NEXT(entry) \
731         ((struct ext4_xattr_entry *)( \
732          (char *)(entry) + EXT4_XATTR_LEN((entry)->e_name_len)))
733 #define EXT4_XATTR_SIZE(size) \
734         (((size) + EXT4_XATTR_ROUND) & ~EXT4_XATTR_ROUND)
735 #define EXT4_XATTR_NAME(entry) \
736         ((char *)((entry) + 1))
737
738 #define EXT4_XATTR_IHDR(raw_inode) \
739         ((struct ext4_xattr_ibody_header *) \
740                 ((char *)raw_inode + \
741                 EXT4_GOOD_OLD_INODE_SIZE + \
742                 (raw_inode)->extra_isize))
743 #define EXT4_XATTR_IFIRST(hdr) \
744         ((struct ext4_xattr_entry *)((hdr)+1))
745
746 #define EXT4_XATTR_BHDR(block) \
747         ((struct ext4_xattr_header *)((block)->data))
748 #define EXT4_XATTR_ENTRY(ptr) \
749         ((struct ext4_xattr_entry *)(ptr))
750 #define EXT4_XATTR_BFIRST(block) \
751         EXT4_XATTR_ENTRY(EXT4_XATTR_BHDR(block)+1)
752 #define EXT4_XATTR_IS_LAST_ENTRY(entry) \
753         (*(uint32_t *)(entry) == 0)
754
755 #define EXT4_ZERO_XATTR_VALUE ((void *)-1)
756
757 /*****************************************************************************/
758
759 #ifdef CONFIG_BIG_ENDIAN
760 static inline uint64_t to_le64(uint64_t n)
761 {
762         return ((n & 0xff) << 56) | ((n & 0xff00) << 40) |
763                 ((n & 0xff0000) << 24) | ((n & 0xff000000LL) << 8) |
764                 ((n & 0xff00000000LL) >> 8) | ((n & 0xff0000000000LL) >> 24) |
765                 ((n & 0xff000000000000LL) >> 40) |
766                 ((n & 0xff00000000000000LL) >> 56);
767 }
768
769 static inline uint32_t to_le32(uint32_t n)
770 {
771         return ((n & 0xff) << 24) | ((n & 0xff00) << 8) |
772                 ((n & 0xff0000) >> 8) | ((n & 0xff000000) >> 24);
773 }
774
775 static inline uint16_t to_le16(uint16_t n)
776 {
777         return ((n & 0xff) << 8) | ((n & 0xff00) >> 8);
778 }
779
780 #else
781 #define to_le64(_n) _n
782 #define to_le32(_n) _n
783 #define to_le16(_n) _n
784 #endif
785
786 /****************************Access macros to ext4 structures*****************/
787
788 #define ext4_get32(s, f) to_le32((s)->f)
789 #define ext4_get16(s, f) to_le16((s)->f)
790 #define ext4_get8(s, f) (s)->f
791
792 #define ext4_set32(s, f, v)                                                    \
793         do {                                                                   \
794                 (s)->f = to_le32(v);                                           \
795         } while (0)
796 #define ext4_set16(s, f, v)                                                    \
797         do {                                                                   \
798                 (s)->f = to_le16(v);                                           \
799         } while (0)
800 #define ext4_set8                                                              \
801         (s, f, v) do { (s)->f = (v); }                                         \
802         while (0)
803
804 #endif /* EXT4_TYPES_H_ */
805
806 /**
807  * @}
808  */