2 * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
6 * Copyright (c) 2012 Martin Sucha
7 * Copyright (c) 2012 Frantisek Princ
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
14 * - Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * - Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * - The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 /** @addtogroup lwext4
39 * @brief Ext4 data structure definitions.
49 #include "ext4_config.h"
50 #include "ext4_blockdev.h"
51 #include "misc/tree.h"
56 #define EXT4_CHECKSUM_CRC32C 1
63 * Structure of the super block
66 uint32_t inodes_count; /* I-nodes count */
67 uint32_t blocks_count_lo; /* Blocks count */
68 uint32_t reserved_blocks_count_lo; /* Reserved blocks count */
69 uint32_t free_blocks_count_lo; /* Free blocks count */
70 uint32_t free_inodes_count; /* Free inodes count */
71 uint32_t first_data_block; /* First Data Block */
72 uint32_t log_block_size; /* Block size */
73 uint32_t log_cluster_size; /* Obsoleted fragment size */
74 uint32_t blocks_per_group; /* Number of blocks per group */
75 uint32_t frags_per_group; /* Obsoleted fragments per group */
76 uint32_t inodes_per_group; /* Number of inodes per group */
77 uint32_t mount_time; /* Mount time */
78 uint32_t write_time; /* Write time */
79 uint16_t mount_count; /* Mount count */
80 uint16_t max_mount_count; /* Maximal mount count */
81 uint16_t magic; /* Magic signature */
82 uint16_t state; /* File system state */
83 uint16_t errors; /* Behavior when detecting errors */
84 uint16_t minor_rev_level; /* Minor revision level */
85 uint32_t last_check_time; /* Time of last check */
86 uint32_t check_interval; /* Maximum time between checks */
87 uint32_t creator_os; /* Creator OS */
88 uint32_t rev_level; /* Revision level */
89 uint16_t def_resuid; /* Default uid for reserved blocks */
90 uint16_t def_resgid; /* Default gid for reserved blocks */
92 /* Fields for EXT4_DYNAMIC_REV superblocks only. */
93 uint32_t first_inode; /* First non-reserved inode */
94 uint16_t inode_size; /* Size of inode structure */
95 uint16_t block_group_index; /* Block group index of this superblock */
96 uint32_t features_compatible; /* Compatible feature set */
97 uint32_t features_incompatible; /* Incompatible feature set */
98 uint32_t features_read_only; /* Readonly-compatible feature set */
99 uint8_t uuid[UUID_SIZE]; /* 128-bit uuid for volume */
100 char volume_name[16]; /* Volume name */
101 char last_mounted[64]; /* Directory where last mounted */
102 uint32_t algorithm_usage_bitmap; /* For compression */
105 * Performance hints. Directory preallocation should only
106 * happen if the EXT4_FEATURE_COMPAT_DIR_PREALLOC flag is on.
108 uint8_t s_prealloc_blocks; /* Number of blocks to try to preallocate */
109 uint8_t s_prealloc_dir_blocks; /* Number to preallocate for dirs */
110 uint16_t s_reserved_gdt_blocks; /* Per group desc for online growth */
113 * Journaling support valid if EXT4_FEATURE_COMPAT_HAS_JOURNAL set.
115 uint8_t journal_uuid[UUID_SIZE]; /* UUID of journal superblock */
116 uint32_t journal_inode_number; /* Inode number of journal file */
117 uint32_t journal_dev; /* Device number of journal file */
118 uint32_t last_orphan; /* Head of list of inodes to delete */
119 uint32_t hash_seed[4]; /* HTREE hash seed */
120 uint8_t default_hash_version; /* Default hash version to use */
121 uint8_t journal_backup_type;
122 uint16_t desc_size; /* Size of group descriptor */
123 uint32_t default_mount_opts; /* Default mount options */
124 uint32_t first_meta_bg; /* First metablock block group */
125 uint32_t mkfs_time; /* When the filesystem was created */
126 uint32_t journal_blocks[17]; /* Backup of the journal inode */
128 /* 64bit support valid if EXT4_FEATURE_COMPAT_64BIT */
129 uint32_t blocks_count_hi; /* Blocks count */
130 uint32_t reserved_blocks_count_hi; /* Reserved blocks count */
131 uint32_t free_blocks_count_hi; /* Free blocks count */
132 uint16_t min_extra_isize; /* All inodes have at least # bytes */
133 uint16_t want_extra_isize; /* New inodes should reserve # bytes */
134 uint32_t flags; /* Miscellaneous flags */
135 uint16_t raid_stride; /* RAID stride */
136 uint16_t mmp_interval; /* # seconds to wait in MMP checking */
137 uint64_t mmp_block; /* Block for multi-mount protection */
138 uint32_t raid_stripe_width; /* Blocks on all data disks (N * stride) */
139 uint8_t log_groups_per_flex; /* FLEX_BG group size */
140 uint8_t checksum_type;
141 uint16_t reserved_pad;
142 uint64_t kbytes_written; /* Number of lifetime kilobytes written */
143 uint32_t snapshot_inum; /* I-node number of active snapshot */
144 uint32_t snapshot_id; /* Sequential ID of active snapshot */
146 snapshot_r_blocks_count; /* Reserved blocks for active snapshot's
149 snapshot_list; /* I-node number of the head of the on-disk snapshot
151 uint32_t error_count; /* Number of file system errors */
152 uint32_t first_error_time; /* First time an error happened */
153 uint32_t first_error_ino; /* I-node involved in first error */
154 uint64_t first_error_block; /* Block involved of first error */
155 uint8_t first_error_func[32]; /* Function where the error happened */
156 uint32_t first_error_line; /* Line number where error happened */
157 uint32_t last_error_time; /* Most recent time of an error */
158 uint32_t last_error_ino; /* I-node involved in last error */
159 uint32_t last_error_line; /* Line number where error happened */
160 uint64_t last_error_block; /* Block involved of last error */
161 uint8_t last_error_func[32]; /* Function where the error happened */
162 uint8_t mount_opts[64];
163 uint32_t usr_quota_inum; /* inode for tracking user quota */
164 uint32_t grp_quota_inum; /* inode for tracking group quota */
165 uint32_t overhead_clusters; /* overhead blocks/clusters in fs */
166 uint32_t backup_bgs[2]; /* groups with sparse_super2 SBs */
167 uint8_t encrypt_algos[4]; /* Encryption algorithms in use */
168 uint8_t encrypt_pw_salt[16]; /* Salt used for string2key algorithm */
169 uint32_t lpf_ino; /* Location of the lost+found inode */
170 uint32_t padding[100]; /* Padding to the end of the block */
171 uint32_t checksum; /* crc32c(superblock) */
176 #define EXT4_SUPERBLOCK_MAGIC 0xEF53
177 #define EXT4_SUPERBLOCK_SIZE 1024
178 #define EXT4_SUPERBLOCK_OFFSET 1024
180 #define EXT4_SUPERBLOCK_OS_LINUX 0
181 #define EXT4_SUPERBLOCK_OS_HURD 1
184 * Misc. filesystem flags
186 #define EXT4_SUPERBLOCK_FLAGS_SIGNED_HASH 0x0001
187 #define EXT4_SUPERBLOCK_FLAGS_UNSIGNED_HASH 0x0002
188 #define EXT4_SUPERBLOCK_FLAGS_TEST_FILESYS 0x0004
192 #define EXT4_SUPERBLOCK_STATE_VALID_FS 0x0001 /* Unmounted cleanly */
193 #define EXT4_SUPERBLOCK_STATE_ERROR_FS 0x0002 /* Errors detected */
194 #define EXT4_SUPERBLOCK_STATE_ORPHAN_FS 0x0004 /* Orphans being recovered */
197 * Behaviour when errors detected
199 #define EXT4_SUPERBLOCK_ERRORS_CONTINUE 1 /* Continue execution */
200 #define EXT4_SUPERBLOCK_ERRORS_RO 2 /* Remount fs read-only */
201 #define EXT4_SUPERBLOCK_ERRORS_PANIC 3 /* Panic */
202 #define EXT4_SUPERBLOCK_ERRORS_DEFAULT EXT4_ERRORS_CONTINUE
205 * Compatible features
207 #define EXT4_FCOM_DIR_PREALLOC 0x0001
208 #define EXT4_FCOM_IMAGIC_INODES 0x0002
209 #define EXT4_FCOM_HAS_JOURNAL 0x0004
210 #define EXT4_FCOM_EXT_ATTR 0x0008
211 #define EXT4_FCOM_RESIZE_INODE 0x0010
212 #define EXT4_FCOM_DIR_INDEX 0x0020
215 * Read-only compatible features
217 #define EXT4_FRO_COM_SPARSE_SUPER 0x0001
218 #define EXT4_FRO_COM_LARGE_FILE 0x0002
219 #define EXT4_FRO_COM_BTREE_DIR 0x0004
220 #define EXT4_FRO_COM_HUGE_FILE 0x0008
221 #define EXT4_FRO_COM_GDT_CSUM 0x0010
222 #define EXT4_FRO_COM_DIR_NLINK 0x0020
223 #define EXT4_FRO_COM_EXTRA_ISIZE 0x0040
224 #define EXT4_FRO_COM_QUOTA 0x0100
225 #define EXT4_FRO_COM_BIGALLOC 0x0200
226 #define EXT4_FRO_COM_METADATA_CSUM 0x0400
229 * Incompatible features
231 #define EXT4_FINCOM_COMPRESSION 0x0001
232 #define EXT4_FINCOM_FILETYPE 0x0002
233 #define EXT4_FINCOM_RECOVER 0x0004 /* Needs recovery */
234 #define EXT4_FINCOM_JOURNAL_DEV 0x0008 /* Journal device */
235 #define EXT4_FINCOM_META_BG 0x0010
236 #define EXT4_FINCOM_EXTENTS 0x0040 /* extents support */
237 #define EXT4_FINCOM_64BIT 0x0080
238 #define EXT4_FINCOM_MMP 0x0100
239 #define EXT4_FINCOM_FLEX_BG 0x0200
240 #define EXT4_FINCOM_EA_INODE 0x0400 /* EA in inode */
241 #define EXT4_FINCOM_DIRDATA 0x1000 /* data in dirent */
242 #define EXT4_FINCOM_BG_USE_META_CSUM 0x2000 /* use crc32c for bg */
243 #define EXT4_FINCOM_LARGEDIR 0x4000 /* >2GB or 3-lvl htree */
244 #define EXT4_FINCOM_INLINE_DATA 0x8000 /* data in inode */
247 * EXT2 supported feature set
249 #define EXT2_SUPPORTED_FCOM 0x0000
251 #define EXT2_SUPPORTED_FINCOM \
252 (EXT4_FINCOM_FILETYPE | EXT4_FINCOM_META_BG)
254 #define EXT2_SUPPORTED_FRO_COM \
255 (EXT4_FRO_COM_SPARSE_SUPER | \
256 EXT4_FRO_COM_LARGE_FILE)
259 * EXT3 supported feature set
261 #define EXT3_SUPPORTED_FCOM (EXT4_FCOM_DIR_INDEX)
263 #define EXT3_SUPPORTED_FINCOM \
264 (EXT4_FINCOM_FILETYPE | EXT4_FINCOM_META_BG)
266 #define EXT3_SUPPORTED_FRO_COM \
267 (EXT4_FRO_COM_SPARSE_SUPER | EXT4_FRO_COM_LARGE_FILE)
270 * EXT4 supported feature set
272 #define EXT4_SUPPORTED_FCOM (EXT4_FCOM_DIR_INDEX)
274 #define EXT4_SUPPORTED_FINCOM \
275 (EXT4_FINCOM_FILETYPE | EXT4_FINCOM_META_BG | \
276 EXT4_FINCOM_EXTENTS | EXT4_FINCOM_FLEX_BG | \
279 #define EXT4_SUPPORTED_FRO_COM \
280 (EXT4_FRO_COM_SPARSE_SUPER | \
281 EXT4_FRO_COM_METADATA_CSUM | \
282 EXT4_FRO_COM_LARGE_FILE | EXT4_FRO_COM_GDT_CSUM | \
283 EXT4_FRO_COM_DIR_NLINK | \
284 EXT4_FRO_COM_EXTRA_ISIZE | EXT4_FRO_COM_HUGE_FILE)
287 * RECOVER - journaling in lwext4 is not supported
288 * (probably won't be ever...)
289 * MMP - multi-mout protection (impossible scenario)
291 #define EXT_FINCOM_IGNORED \
292 EXT4_FINCOM_RECOVER | EXT4_FINCOM_MMP
295 /*TODO: Features incompatible to implement*/
296 #define EXT4_SUPPORTED_FINCOM
297 (EXT4_FINCOM_INLINE_DATA)
299 /*TODO: Features read only to implement*/
300 #define EXT4_SUPPORTED_FRO_COM
301 EXT4_FRO_COM_BIGALLOC |\
306 struct ext4_blockdev *bdev;
307 struct ext4_sblock sb;
309 uint64_t inode_block_limits[4];
310 uint64_t inode_blocks_per_level[4];
312 uint32_t last_inode_bg_id;
314 struct jbd_fs *jbd_fs;
315 struct jbd_journal *jbd_journal;
316 struct jbd_trans *curr_trans;
319 /* Inode table/bitmap not in use */
320 #define EXT4_BLOCK_GROUP_INODE_UNINIT 0x0001
321 /* Block bitmap not in use */
322 #define EXT4_BLOCK_GROUP_BLOCK_UNINIT 0x0002
323 /* On-disk itable initialized to zero */
324 #define EXT4_BLOCK_GROUP_ITABLE_ZEROED 0x0004
327 * Structure of a blocks group descriptor
330 uint32_t block_bitmap_lo; /* Blocks bitmap block */
331 uint32_t inode_bitmap_lo; /* Inodes bitmap block */
332 uint32_t inode_table_first_block_lo; /* Inodes table block */
333 uint16_t free_blocks_count_lo; /* Free blocks count */
334 uint16_t free_inodes_count_lo; /* Free inodes count */
335 uint16_t used_dirs_count_lo; /* Directories count */
336 uint16_t flags; /* EXT4_BG_flags (INODE_UNINIT, etc) */
337 uint32_t exclude_bitmap_lo; /* Exclude bitmap for snapshots */
338 uint16_t block_bitmap_csum_lo; /* crc32c(s_uuid+grp_num+bbitmap) LE */
339 uint16_t inode_bitmap_csum_lo; /* crc32c(s_uuid+grp_num+ibitmap) LE */
340 uint16_t itable_unused_lo; /* Unused inodes count */
341 uint16_t checksum; /* crc16(sb_uuid+group+desc) */
343 uint32_t block_bitmap_hi; /* Blocks bitmap block MSB */
344 uint32_t inode_bitmap_hi; /* I-nodes bitmap block MSB */
345 uint32_t inode_table_first_block_hi; /* I-nodes table block MSB */
346 uint16_t free_blocks_count_hi; /* Free blocks count MSB */
347 uint16_t free_inodes_count_hi; /* Free i-nodes count MSB */
348 uint16_t used_dirs_count_hi; /* Directories count MSB */
349 uint16_t itable_unused_hi; /* Unused inodes count MSB */
350 uint32_t exclude_bitmap_hi; /* Exclude bitmap block MSB */
351 uint16_t block_bitmap_csum_hi; /* crc32c(s_uuid+grp_num+bbitmap) BE */
352 uint16_t inode_bitmap_csum_hi; /* crc32c(s_uuid+grp_num+ibitmap) BE */
353 uint32_t reserved; /* Padding */
356 struct ext4_block_group_ref {
357 struct ext4_block block;
358 struct ext4_bgroup *block_group;
364 #define EXT4_MIN_BLOCK_GROUP_DESCRIPTOR_SIZE 32
365 #define EXT4_MAX_BLOCK_GROUP_DESCRIPTOR_SIZE 64
367 #define EXT4_MIN_BLOCK_SIZE 1024 /* 1 KiB */
368 #define EXT4_MAX_BLOCK_SIZE 65536 /* 64 KiB */
369 #define EXT4_REV0_INODE_SIZE 128
371 #define EXT4_INODE_BLOCK_SIZE 512
373 #define EXT4_INODE_DIRECT_BLOCK_COUNT 12
374 #define EXT4_INODE_INDIRECT_BLOCK EXT4_INODE_DIRECT_BLOCK_COUNT
375 #define EXT4_INODE_DOUBLE_INDIRECT_BLOCK (EXT4_INODE_INDIRECT_BLOCK + 1)
376 #define EXT4_INODE_TRIPPLE_INDIRECT_BLOCK (EXT4_INODE_DOUBLE_INDIRECT_BLOCK + 1)
377 #define EXT4_INODE_BLOCKS (EXT4_INODE_TRIPPLE_INDIRECT_BLOCK + 1)
378 #define EXT4_INODE_INDIRECT_BLOCK_COUNT \
379 (EXT4_INODE_BLOCKS - EXT4_INODE_DIRECT_BLOCK_COUNT)
381 #pragma pack(push, 1)
384 * Structure of an inode on the disk
387 uint16_t mode; /* File mode */
388 uint16_t uid; /* Low 16 bits of owner uid */
389 uint32_t size_lo; /* Size in bytes */
390 uint32_t access_time; /* Access time */
391 uint32_t change_inode_time; /* I-node change time */
392 uint32_t modification_time; /* Modification time */
393 uint32_t deletion_time; /* Deletion time */
394 uint16_t gid; /* Low 16 bits of group id */
395 uint16_t links_count; /* Links count */
396 uint32_t blocks_count_lo; /* Blocks count */
397 uint32_t flags; /* File flags */
398 uint32_t unused_osd1; /* OS dependent - not used in HelenOS */
399 uint32_t blocks[EXT4_INODE_BLOCKS]; /* Pointers to blocks */
400 uint32_t generation; /* File version (for NFS) */
401 uint32_t file_acl_lo; /* File ACL */
403 uint32_t obso_faddr; /* Obsoleted fragment address */
407 uint16_t blocks_high;
408 uint16_t file_acl_high;
411 uint16_t checksum_lo; /* crc32c(uuid+inum+inode) LE */
423 uint16_t extra_isize;
424 uint16_t checksum_hi; /* crc32c(uuid+inum+inode) BE */
425 uint32_t ctime_extra; /* Extra change time (nsec << 2 | epoch) */
426 uint32_t mtime_extra; /* Extra Modification time (nsec << 2 | epoch) */
427 uint32_t atime_extra; /* Extra Access time (nsec << 2 | epoch) */
428 uint32_t crtime; /* File creation time */
430 crtime_extra; /* Extra file creation time (nsec << 2 | epoch) */
431 uint32_t version_hi; /* High 32 bits for 64-bit version */
436 #define EXT4_INODE_MODE_FIFO 0x1000
437 #define EXT4_INODE_MODE_CHARDEV 0x2000
438 #define EXT4_INODE_MODE_DIRECTORY 0x4000
439 #define EXT4_INODE_MODE_BLOCKDEV 0x6000
440 #define EXT4_INODE_MODE_FILE 0x8000
441 #define EXT4_INODE_MODE_SOFTLINK 0xA000
442 #define EXT4_INODE_MODE_SOCKET 0xC000
443 #define EXT4_INODE_MODE_TYPE_MASK 0xF000
448 #define EXT4_INODE_FLAG_SECRM 0x00000001 /* Secure deletion */
449 #define EXT4_INODE_FLAG_UNRM 0x00000002 /* Undelete */
450 #define EXT4_INODE_FLAG_COMPR 0x00000004 /* Compress file */
451 #define EXT4_INODE_FLAG_SYNC 0x00000008 /* Synchronous updates */
452 #define EXT4_INODE_FLAG_IMMUTABLE 0x00000010 /* Immutable file */
453 #define EXT4_INODE_FLAG_APPEND 0x00000020 /* writes to file may only append */
454 #define EXT4_INODE_FLAG_NODUMP 0x00000040 /* do not dump file */
455 #define EXT4_INODE_FLAG_NOATIME 0x00000080 /* do not update atime */
457 /* Compression flags */
458 #define EXT4_INODE_FLAG_DIRTY 0x00000100
459 #define EXT4_INODE_FLAG_COMPRBLK \
460 0x00000200 /* One or more compressed clusters */
461 #define EXT4_INODE_FLAG_NOCOMPR 0x00000400 /* Don't compress */
462 #define EXT4_INODE_FLAG_ECOMPR 0x00000800 /* Compression error */
464 #define EXT4_INODE_FLAG_INDEX 0x00001000 /* hash-indexed directory */
465 #define EXT4_INODE_FLAG_IMAGIC 0x00002000 /* AFS directory */
466 #define EXT4_INODE_FLAG_JOURNAL_DATA \
467 0x00004000 /* File data should be journaled */
468 #define EXT4_INODE_FLAG_NOTAIL 0x00008000 /* File tail should not be merged */
469 #define EXT4_INODE_FLAG_DIRSYNC \
470 0x00010000 /* Dirsync behaviour (directories only) */
471 #define EXT4_INODE_FLAG_TOPDIR 0x00020000 /* Top of directory hierarchies */
472 #define EXT4_INODE_FLAG_HUGE_FILE 0x00040000 /* Set to each huge file */
473 #define EXT4_INODE_FLAG_EXTENTS 0x00080000 /* Inode uses extents */
474 #define EXT4_INODE_FLAG_EA_INODE 0x00200000 /* Inode used for large EA */
475 #define EXT4_INODE_FLAG_EOFBLOCKS 0x00400000 /* Blocks allocated beyond EOF */
476 #define EXT4_INODE_FLAG_RESERVED 0x80000000 /* reserved for ext4 lib */
478 #define EXT4_INODE_ROOT_INDEX 2
480 struct ext4_inode_ref {
481 struct ext4_block block;
482 struct ext4_inode *inode;
488 #define EXT4_DIRECTORY_FILENAME_LEN 255
490 /**@brief Directory entry types. */
491 enum { EXT4_DE_UNKNOWN = 0,
500 #define EXT4_DIRENTRY_DIR_CSUM 0xDE
502 #pragma pack(push, 1)
504 union ext4_dir_en_internal {
505 uint8_t name_length_high; /* Higher 8 bits of name length */
506 uint8_t inode_type; /* Type of referenced inode (in rev >= 0.5) */
510 * Linked list directory entry structure
513 uint32_t inode; /* I-node for the entry */
514 uint16_t entry_len; /* Distance to the next directory entry */
515 uint8_t name_len; /* Lower 8 bits of name length */
517 union ext4_dir_en_internal in;
519 uint8_t name[EXT4_DIRECTORY_FILENAME_LEN]; /* Entry name */
522 struct ext4_dir_iter {
523 struct ext4_inode_ref *inode_ref;
524 struct ext4_block curr_blk;
526 struct ext4_dir_en *curr;
529 struct ext4_dir_search_result {
530 struct ext4_block block;
531 struct ext4_dir_en *dentry;
534 /* Structures for indexed directory */
536 struct ext4_dir_idx_climit {
541 struct ext4_dir_idx_dot_en {
543 uint16_t entry_length;
549 struct ext4_dir_idx_rinfo {
550 uint32_t reserved_zero;
551 uint8_t hash_version;
553 uint8_t indirect_levels;
554 uint8_t unused_flags;
557 struct ext4_dir_idx_entry {
562 struct ext4_dir_idx_root {
563 struct ext4_dir_idx_dot_en dots[2];
564 struct ext4_dir_idx_rinfo info;
565 struct ext4_dir_idx_entry en[];
568 struct ext4_fake_dir_entry {
570 uint16_t entry_length;
575 struct ext4_dir_idx_node {
576 struct ext4_fake_dir_entry fake;
577 struct ext4_dir_idx_entry entries[];
580 struct ext4_dir_idx_block {
582 struct ext4_dir_idx_entry *entries;
583 struct ext4_dir_idx_entry *position;
587 * This goes at the end of each htree block.
589 struct ext4_dir_idx_tail {
591 uint32_t checksum; /* crc32c(uuid+inum+dirblock) */
595 * This is a bogus directory entry at the end of each leaf block that
598 struct ext4_dir_entry_tail {
599 uint32_t reserved_zero1; /* Pretend to be unused */
600 uint16_t rec_len; /* 12 */
601 uint8_t reserved_zero2; /* Zero name length */
602 uint8_t reserved_ft; /* 0xDE, fake file type */
603 uint32_t checksum; /* crc32c(uuid+inum+dirblock) */
608 #define EXT4_DIRENT_TAIL(block, blocksize) \
609 ((struct ext4_dir_entry_tail *)(((char *)(block)) + ((blocksize) - \
610 sizeof(struct ext4_dir_entry_tail))))
612 #define EXT4_ERR_BAD_DX_DIR (-25000)
614 #define EXT4_LINK_MAX 65000
616 #define EXT4_BAD_INO 1
617 #define EXT4_ROOT_INO 2
618 #define EXT4_BOOT_LOADER_INO 5
619 #define EXT4_UNDEL_DIR_INO 6
620 #define EXT4_RESIZE_INO 7
621 #define EXT4_JOURNAL_INO 8
623 #define EXT4_GOOD_OLD_FIRST_INO 11
625 #define EXT4_EXT_UNWRITTEN_MASK (1L << 15)
627 #define EXT4_EXT_MAX_LEN_WRITTEN (1L << 15)
628 #define EXT4_EXT_MAX_LEN_UNWRITTEN \
629 (EXT4_EXT_MAX_LEN_WRITTEN - 1)
631 #define EXT4_EXT_GET_LEN(ex) to_le16((ex)->block_count)
632 #define EXT4_EXT_GET_LEN_UNWRITTEN(ex) \
633 (EXT4_EXT_GET_LEN(ex) &= ~(EXT4_EXT_UNWRITTEN_MASK))
634 #define EXT4_EXT_SET_LEN(ex, count) \
635 ((ex)->block_count = to_le16(count))
637 #define EXT4_EXT_IS_UNWRITTEN(ex) \
638 (EXT4_EXT_GET_LEN(ex) > EXT4_EXT_MAX_LEN_WRITTEN)
639 #define EXT4_EXT_SET_UNWRITTEN(ex) \
640 ((ex)->block_count |= to_le16(EXT4_EXT_UNWRITTEN_MASK))
641 #define EXT4_EXT_SET_WRITTEN(ex) \
642 ((ex)->block_count &= ~(to_le16(EXT4_EXT_UNWRITTEN_MASK)))
644 #pragma pack(push, 1)
647 * This is the extent tail on-disk structure.
648 * All other extent structures are 12 bytes long. It turns out that
649 * block_size % 12 >= 4 for at least all powers of 2 greater than 512, which
650 * covers all valid ext4 block sizes. Therefore, this tail structure can be
651 * crammed into the end of the block without having to rebalance the tree.
653 struct ext4_extent_tail
655 uint32_t et_checksum; /* crc32c(uuid+inum+extent_block) */
659 * This is the extent on-disk structure.
660 * It's used at the bottom of the tree.
663 uint32_t first_block; /* First logical block extent covers */
664 uint16_t block_count; /* Number of blocks covered by extent */
665 uint16_t start_hi; /* High 16 bits of physical block */
666 uint32_t start_lo; /* Low 32 bits of physical block */
670 * This is index on-disk structure.
671 * It's used at all the levels except the bottom.
673 struct ext4_extent_index {
674 uint32_t first_block; /* Index covers logical blocks from 'block' */
677 * Pointer to the physical block of the next
678 * level. leaf or next index could be there
679 * high 16 bits of physical block
687 * Each block (leaves and indexes), even inode-stored has header.
689 struct ext4_extent_header {
691 uint16_t entries_count; /* Number of valid entries */
692 uint16_t max_entries_count; /* Capacity of store in entries */
693 uint16_t depth; /* Has tree real underlying blocks? */
694 uint32_t generation; /* generation of the tree */
703 typedef uint32_t ext4_lblk_t;
704 typedef uint64_t ext4_fsblk_t;
707 * Array of ext4_ext_path contains path to some extent.
708 * Creation/lookup routines use it for traversal/splitting/etc.
709 * Truncate uses it to simulate recursive walking.
711 struct ext4_extent_path {
712 ext4_fsblk_t p_block;
713 struct ext4_block block;
716 struct ext4_extent_header *header;
717 struct ext4_extent_index *index;
718 struct ext4_extent *extent;
723 #define EXT4_EXTENT_MAGIC 0xF30A
725 #define EXT4_EXTENT_FIRST(header) \
726 ((struct ext4_extent *)(((char *)(header)) + \
727 sizeof(struct ext4_extent_header)))
729 #define EXT4_EXTENT_FIRST_INDEX(header) \
730 ((struct ext4_extent_index *)(((char *)(header)) + \
731 sizeof(struct ext4_extent_header)))
734 * EXT_INIT_MAX_LEN is the maximum number of blocks we can have in an
735 * initialized extent. This is 2^15 and not (2^16 - 1), since we use the
736 * MSB of ee_len field in the extent datastructure to signify if this
737 * particular extent is an initialized extent or an uninitialized (i.e.
739 * EXT_UNINIT_MAX_LEN is the maximum number of blocks we can have in an
740 * uninitialized extent.
741 * If ee_len is <= 0x8000, it is an initialized extent. Otherwise, it is an
742 * uninitialized one. In other words, if MSB of ee_len is set, it is an
743 * uninitialized extent with only one special scenario when ee_len = 0x8000.
744 * In this case we can not have an uninitialized extent of zero length and
745 * thus we make it as a special case of initialized extent with 0x8000 length.
746 * This way we get better extent-to-group alignment for initialized extents.
747 * Hence, the maximum number of blocks we can have in an *initialized*
748 * extent is 2^15 (32768) and in an *uninitialized* extent is 2^15-1 (32767).
750 #define EXT_INIT_MAX_LEN (1L << 15)
751 #define EXT_UNWRITTEN_MAX_LEN (EXT_INIT_MAX_LEN - 1)
753 #define EXT_EXTENT_SIZE sizeof(struct ext4_extent)
754 #define EXT_INDEX_SIZE sizeof(struct ext4_extent_idx)
756 #define EXT_FIRST_EXTENT(__hdr__) \
757 ((struct ext4_extent *)(((char *)(__hdr__)) + \
758 sizeof(struct ext4_extent_header)))
759 #define EXT_FIRST_INDEX(__hdr__) \
760 ((struct ext4_extent_index *)(((char *)(__hdr__)) + \
761 sizeof(struct ext4_extent_header)))
762 #define EXT_HAS_FREE_INDEX(__path__) \
763 ((__path__)->header->entries_count < (__path__)->header->max_entries_count)
764 #define EXT_LAST_EXTENT(__hdr__) \
765 (EXT_FIRST_EXTENT((__hdr__)) + (__hdr__)->entries_count - 1)
766 #define EXT_LAST_INDEX(__hdr__) \
767 (EXT_FIRST_INDEX((__hdr__)) + (__hdr__)->entries_count - 1)
768 #define EXT_MAX_EXTENT(__hdr__) \
769 (EXT_FIRST_EXTENT((__hdr__)) + (__hdr__)->max_entries_count - 1)
770 #define EXT_MAX_INDEX(__hdr__) \
771 (EXT_FIRST_INDEX((__hdr__)) + (__hdr__)->max_entries_count - 1)
773 #define EXT4_EXTENT_TAIL_OFFSET(hdr) \
774 (sizeof(struct ext4_extent_header) + \
775 (sizeof(struct ext4_extent) * (hdr)->max_entries_count))
778 * ext4_ext_next_allocated_block:
779 * returns allocated block in subsequent extent or EXT_MAX_BLOCKS.
780 * NOTE: it considers block number from index entry as
781 * allocated block. Thus, index entries have to be consistent
784 #define EXT_MAX_BLOCKS (ext4_lblk_t) (-1)
786 #define IN_RANGE(b, first, len) ((b) >= (first) && (b) <= (first) + (len) - 1)
789 /******************************************************************************/
791 /* EXT3 HTree directory indexing */
792 #define EXT2_HTREE_LEGACY 0
793 #define EXT2_HTREE_HALF_MD4 1
794 #define EXT2_HTREE_TEA 2
795 #define EXT2_HTREE_LEGACY_UNSIGNED 3
796 #define EXT2_HTREE_HALF_MD4_UNSIGNED 4
797 #define EXT2_HTREE_TEA_UNSIGNED 5
799 #define EXT2_HTREE_EOF 0x7FFFFFFFUL
801 struct ext4_hash_info {
804 uint32_t hash_version;
805 const uint32_t *seed;
808 /* Extended Attribute(EA) */
810 /* Magic value in attribute blocks */
811 #define EXT4_XATTR_MAGIC 0xEA020000
813 /* Maximum number of references to one attribute block */
814 #define EXT4_XATTR_REFCOUNT_MAX 1024
817 #define EXT4_XATTR_INDEX_USER 1
818 #define EXT4_XATTR_INDEX_POSIX_ACL_ACCESS 2
819 #define EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT 3
820 #define EXT4_XATTR_INDEX_TRUSTED 4
821 #define EXT4_XATTR_INDEX_LUSTRE 5
822 #define EXT4_XATTR_INDEX_SECURITY 6
823 #define EXT4_XATTR_INDEX_SYSTEM 7
824 #define EXT4_XATTR_INDEX_RICHACL 8
825 #define EXT4_XATTR_INDEX_ENCRYPTION 9
827 #pragma pack(push, 1)
829 struct ext4_xattr_header {
830 uint32_t h_magic; /* magic number for identification */
831 uint32_t h_refcount; /* reference count */
832 uint32_t h_blocks; /* number of disk blocks used */
833 uint32_t h_hash; /* hash value of all attributes */
834 uint32_t h_checksum; /* crc32c(uuid+id+xattrblock) */
835 /* id = inum if refcount=1, blknum otherwise */
836 uint32_t h_reserved[3]; /* zero right now */
839 struct ext4_xattr_ibody_header {
840 uint32_t h_magic; /* magic number for identification */
843 struct ext4_xattr_entry {
844 uint8_t e_name_len; /* length of name */
845 uint8_t e_name_index; /* attribute name index */
846 uint16_t e_value_offs; /* offset in disk block of value */
847 uint32_t e_value_block; /* disk block attribute is stored on (n/i) */
848 uint32_t e_value_size; /* size of attribute value */
849 uint32_t e_hash; /* hash value of name and value */
854 struct ext4_xattr_item {
855 /* This attribute should be stored in inode body */
864 RB_ENTRY(ext4_xattr_item) node;
867 struct ext4_xattr_ref {
869 struct ext4_block block;
870 struct ext4_inode_ref *inode_ref;
876 struct ext4_xattr_item *iter_from;
878 RB_HEAD(ext4_xattr_tree,
879 ext4_xattr_item) root;
882 #define EXT4_XATTR_ITERATE_CONT 0
883 #define EXT4_XATTR_ITERATE_STOP 1
884 #define EXT4_XATTR_ITERATE_PAUSE 2
886 #define EXT4_GOOD_OLD_INODE_SIZE 128
888 #define EXT4_XATTR_PAD_BITS 2
889 #define EXT4_XATTR_PAD (1<<EXT4_XATTR_PAD_BITS)
890 #define EXT4_XATTR_ROUND (EXT4_XATTR_PAD-1)
891 #define EXT4_XATTR_LEN(name_len) \
892 (((name_len) + EXT4_XATTR_ROUND + \
893 sizeof(struct ext4_xattr_entry)) & ~EXT4_XATTR_ROUND)
894 #define EXT4_XATTR_NEXT(entry) \
895 ((struct ext4_xattr_entry *)( \
896 (char *)(entry) + EXT4_XATTR_LEN((entry)->e_name_len)))
897 #define EXT4_XATTR_SIZE(size) \
898 (((size) + EXT4_XATTR_ROUND) & ~EXT4_XATTR_ROUND)
899 #define EXT4_XATTR_NAME(entry) \
900 ((char *)((entry) + 1))
902 #define EXT4_XATTR_IHDR(raw_inode) \
903 ((struct ext4_xattr_ibody_header *) \
904 ((char *)raw_inode + \
905 EXT4_GOOD_OLD_INODE_SIZE + \
906 (raw_inode)->extra_isize))
907 #define EXT4_XATTR_IFIRST(hdr) \
908 ((struct ext4_xattr_entry *)((hdr)+1))
910 #define EXT4_XATTR_BHDR(block) \
911 ((struct ext4_xattr_header *)((block)->data))
912 #define EXT4_XATTR_ENTRY(ptr) \
913 ((struct ext4_xattr_entry *)(ptr))
914 #define EXT4_XATTR_BFIRST(block) \
915 EXT4_XATTR_ENTRY(EXT4_XATTR_BHDR(block)+1)
916 #define EXT4_XATTR_IS_LAST_ENTRY(entry) \
917 (*(uint32_t *)(entry) == 0)
919 #define EXT4_ZERO_XATTR_VALUE ((void *)-1)
921 /*****************************************************************************/
924 * JBD stores integers in big endian.
927 #define JBD_MAGIC_NUMBER 0xc03b3998U /* The first 4 bytes of /dev/random! */
930 * Descriptor block types:
933 #define JBD_DESCRIPTOR_BLOCK 1
934 #define JBD_COMMIT_BLOCK 2
935 #define JBD_SUPERBLOCK 3
936 #define JBD_SUPERBLOCK_V2 4
937 #define JBD_REVOKE_BLOCK 5
939 #pragma pack(push, 1)
942 * Standard header for all descriptor blocks:
955 #define JBD_CRC32_CHKSUM 1
956 #define JBD_MD5_CHKSUM 2
957 #define JBD_SHA1_CHKSUM 3
958 #define JBD_CRC32C_CHKSUM 4
960 #define JBD_CRC32_CHKSUM_SIZE 4
962 #define JBD_CHECKSUM_BYTES (32 / sizeof(uint32_t))
964 #pragma pack(push, 1)
967 * Commit block header for storing transactional checksums:
969 * NOTE: If FEATURE_COMPAT_CHECKSUM (checksum v1) is set, the h_chksum*
970 * fields are used to store a checksum of the descriptor and data blocks.
972 * If FEATURE_INCOMPAT_CSUM_V2 (checksum v2) is set, then the h_chksum
973 * field is used to store crc32c(uuid+commit_block). Each journal metadata
974 * block gets its own checksum, and data block checksums are stored in
975 * journal_block_tag (in the descriptor). The other h_chksum* fields are
978 * If FEATURE_INCOMPAT_CSUM_V3 is set, the descriptor block uses
979 * journal_block_tag3_t to store a full 32-bit checksum. Everything else
982 * Checksum v1, v2, and v3 are mutually exclusive features.
985 struct jbd_commit_header {
986 struct jbd_bhdr header;
990 uint32_t chksum[JBD_CHECKSUM_BYTES];
992 uint32_t commit_nsec;
996 * The block tag: used to describe a single buffer in the journal
998 struct jbd_block_tag3 {
999 uint32_t blocknr; /* The on-disk block number */
1000 uint32_t flags; /* See below */
1001 uint32_t blocknr_high; /* most-significant high 32bits. */
1002 uint32_t checksum; /* crc32c(uuid+seq+block) */
1005 struct jbd_block_tag {
1006 uint32_t blocknr; /* The on-disk block number */
1007 uint16_t checksum; /* truncated crc32c(uuid+seq+block) */
1008 uint16_t flags; /* See below */
1009 uint32_t blocknr_high; /* most-significant high 32bits. */
1014 /* Definitions for the journal tag flags word: */
1015 #define JBD_FLAG_ESCAPE 1 /* on-disk block is escaped */
1016 #define JBD_FLAG_SAME_UUID 2 /* block has same uuid as previous */
1017 #define JBD_FLAG_DELETED 4 /* block deleted by this transaction */
1018 #define JBD_FLAG_LAST_TAG 8 /* last tag in this descriptor block */
1020 #pragma pack(push, 1)
1022 /* Tail of descriptor block, for checksumming */
1023 struct jbd_block_tail {
1028 * The revoke descriptor: used on disk to describe a series of blocks to
1029 * be revoked from the log
1031 struct jbd_revoke_header {
1032 struct jbd_bhdr header;
1033 uint32_t count; /* Count of bytes used in the block */
1036 /* Tail of revoke block, for checksumming */
1037 struct jbd_revoke_tail {
1043 #define JBD_USERS_MAX 48
1044 #define JBD_USERS_SIZE (UUID_SIZE * JBD_USERS_MAX)
1046 #pragma pack(push, 1)
1049 * The journal superblock. All fields are in big-endian byte order.
1053 struct jbd_bhdr header;
1056 /* Static information describing the journal */
1057 uint32_t blocksize; /* journal device blocksize */
1058 uint32_t maxlen; /* total blocks in journal file */
1059 uint32_t first; /* first block of log information */
1062 /* Dynamic information describing the current state of the log */
1063 uint32_t sequence; /* first commit ID expected in log */
1064 uint32_t start; /* blocknr of start of log */
1067 /* Error value, as set by journal_abort(). */
1071 /* Remaining fields are only valid in a version-2 superblock */
1072 uint32_t feature_compat; /* compatible feature set */
1073 uint32_t feature_incompat; /* incompatible feature set */
1074 uint32_t feature_ro_compat; /* readonly-compatible feature set */
1076 uint8_t uuid[UUID_SIZE]; /* 128-bit uuid for journal */
1079 uint32_t nr_users; /* Nr of filesystems sharing log */
1081 uint32_t dynsuper; /* Blocknr of dynamic superblock copy*/
1084 uint32_t max_transaction; /* Limit of journal blocks per trans.*/
1085 uint32_t max_trandata; /* Limit of data blocks per trans. */
1088 uint8_t checksum_type; /* checksum type */
1089 uint8_t padding2[3];
1090 uint32_t padding[42];
1091 uint32_t checksum; /* crc32c(superblock) */
1094 uint8_t users[JBD_USERS_SIZE]; /* ids of all fs'es sharing the log */
1101 #define JBD_SUPERBLOCK_SIZE sizeof(struct jbd_sb)
1103 #define JBD_HAS_COMPAT_FEATURE(jsb,mask) \
1104 ((jsb)->header.blocktype >= to_be32(2) && \
1105 ((jsb)->feature_compat & to_be32((mask))))
1106 #define JBD_HAS_RO_COMPAT_FEATURE(jsb,mask) \
1107 ((jsb)->header.blocktype >= to_be32(2) && \
1108 ((jsb)->feature_ro_compat & to_be32((mask))))
1109 #define JBD_HAS_INCOMPAT_FEATURE(jsb,mask) \
1110 ((jsb)->header.blocktype >= to_be32(2) && \
1111 ((jsb)->feature_incompat & to_be32((mask))))
1113 #define JBD_FEATURE_COMPAT_CHECKSUM 0x00000001
1115 #define JBD_FEATURE_INCOMPAT_REVOKE 0x00000001
1116 #define JBD_FEATURE_INCOMPAT_64BIT 0x00000002
1117 #define JBD_FEATURE_INCOMPAT_ASYNC_COMMIT 0x00000004
1118 #define JBD_FEATURE_INCOMPAT_CSUM_V2 0x00000008
1119 #define JBD_FEATURE_INCOMPAT_CSUM_V3 0x00000010
1121 /* Features known to this kernel version: */
1122 #define JBD_KNOWN_COMPAT_FEATURES 0
1123 #define JBD_KNOWN_ROCOMPAT_FEATURES 0
1124 #define JBD_KNOWN_INCOMPAT_FEATURES (JBD_FEATURE_INCOMPAT_REVOKE|\
1125 JBD_FEATURE_INCOMPAT_ASYNC_COMMIT|\
1126 JBD_FEATURE_INCOMPAT_64BIT|\
1127 JBD_FEATURE_INCOMPAT_CSUM_V2|\
1128 JBD_FEATURE_INCOMPAT_CSUM_V3)
1131 /* If journal block device is used, bdev will be non-null */
1132 struct ext4_blockdev *bdev;
1133 struct ext4_inode_ref inode_ref;
1141 struct ext4_block block;
1142 struct jbd_trans *trans;
1143 struct jbd_block_rec *block_rec;
1144 TAILQ_ENTRY(jbd_buf) buf_node;
1145 TAILQ_ENTRY(jbd_buf) dirty_buf_node;
1148 struct jbd_revoke_rec {
1150 LIST_ENTRY(jbd_revoke_rec) revoke_node;
1153 struct jbd_block_rec {
1155 struct ext4_buf *buf;
1156 struct jbd_trans *trans;
1157 RB_ENTRY(jbd_block_rec) block_rec_node;
1158 LIST_ENTRY(jbd_block_rec) tbrec_node;
1159 TAILQ_HEAD(jbd_buf_dirty, jbd_buf) dirty_buf_queue;
1165 uint32_t start_iblock;
1172 struct jbd_journal *journal;
1174 TAILQ_HEAD(jbd_trans_buf, jbd_buf) buf_queue;
1175 LIST_HEAD(jbd_revoke_list, jbd_revoke_rec) revoke_list;
1176 LIST_HEAD(jbd_trans_block_rec, jbd_block_rec) tbrec_list;
1177 TAILQ_ENTRY(jbd_trans) trans_node;
1180 struct jbd_journal {
1185 uint32_t alloc_trans_id;
1187 uint32_t block_size;
1189 TAILQ_HEAD(jbd_trans_queue, jbd_trans) trans_queue;
1190 TAILQ_HEAD(jbd_cp_queue, jbd_trans) cp_queue;
1191 RB_HEAD(jbd_block, jbd_block_rec) block_rec_root;
1193 struct jbd_fs *jbd_fs;
1196 /*****************************************************************************/
1198 #define EXT4_CRC32_INIT (0xFFFFFFFFUL)
1200 /*****************************************************************************/
1202 static inline uint64_t reorder64(uint64_t n)
1204 return ((n & 0xff) << 56) |
1205 ((n & 0xff00) << 40) |
1206 ((n & 0xff0000) << 24) |
1207 ((n & 0xff000000LL) << 8) |
1208 ((n & 0xff00000000LL) >> 8) |
1209 ((n & 0xff0000000000LL) >> 24) |
1210 ((n & 0xff000000000000LL) >> 40) |
1211 ((n & 0xff00000000000000LL) >> 56);
1214 static inline uint32_t reorder32(uint32_t n)
1216 return ((n & 0xff) << 24) |
1217 ((n & 0xff00) << 8) |
1218 ((n & 0xff0000) >> 8) |
1219 ((n & 0xff000000) >> 24);
1222 static inline uint16_t reorder16(uint16_t n)
1224 return ((n & 0xff) << 8) |
1225 ((n & 0xff00) >> 8);
1228 #ifdef CONFIG_BIG_ENDIAN
1229 #define to_le64(_n) reorder64(_n)
1230 #define to_le32(_n) reorder32(_n)
1231 #define to_le16(_n) reorder16(_n)
1233 #define to_be64(_n) _n
1234 #define to_be32(_n) _n
1235 #define to_be16(_n) _n
1238 #define to_le64(_n) _n
1239 #define to_le32(_n) _n
1240 #define to_le16(_n) _n
1242 #define to_be64(_n) reorder64(_n)
1243 #define to_be32(_n) reorder32(_n)
1244 #define to_be16(_n) reorder16(_n)
1247 /****************************Access macros to ext4 structures*****************/
1249 #define ext4_get32(s, f) to_le32((s)->f)
1250 #define ext4_get16(s, f) to_le16((s)->f)
1251 #define ext4_get8(s, f) (s)->f
1253 #define ext4_set32(s, f, v) \
1255 (s)->f = to_le32(v); \
1257 #define ext4_set16(s, f, v) \
1259 (s)->f = to_le16(v); \
1262 (s, f, v) do { (s)->f = (v); } \
1265 /****************************Access macros to jbd2 structures*****************/
1267 #define jbd_get32(s, f) to_be32((s)->f)
1268 #define jbd_get16(s, f) to_be16((s)->f)
1269 #define jbd_get8(s, f) (s)->f
1271 #define jbd_set32(s, f, v) \
1273 (s)->f = to_be32(v); \
1275 #define jbd_set16(s, f, v) \
1277 (s)->f = to_be16(v); \
1280 (s, f, v) do { (s)->f = (v); } \
1285 #define __unused __attribute__ ((__unused__))
1292 #define offsetof(type, field) \
1293 ((size_t)(&(((type *)0)->field)))
1300 #endif /* EXT4_TYPES_H_ */