1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312
|
#ifndef __EXT2_FS_H
#define __EXT2_FS_H
#include <stdint.h>
#define EXT2_SUPER_MAGIC 0xEF53
#define EXT2_GOOD_OLD_REV 0 // The good old (original) format
#define EXT2_DYNAMIC_REV 1 // V2 format w/ dynamic inode sizes
#define EXT2_GOOD_OLD_INODE_SIZE 128
// Special inode numbers
#define EXT2_BAD_INO 1 // Bad blocks inode
#define EXT2_ROOT_INO 2 // Root inode
#define EXT2_BOOT_LOADER_INO 5 // Boot loader inode
#define EXT2_UNDEL_DIR_INO 6 // Undelete directory inode
#define EXT3_RESIZE_INO 7 // Reserved group descriptors inode
#define EXT3_JOURNAL_INO 8 // Journal inode
// We're readonly, so we only care about incompat features.
#define EXT2_FEATURE_INCOMPAT_COMPRESSION 0x0001
#define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002
#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004
#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008
#define EXT2_FEATURE_INCOMPAT_META_BG 0x0010
#define EXT2_FEATURE_INCOMPAT_ANY 0xffffffff
#define EXT2_NDIR_BLOCKS 12
#define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS
#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK+1)
#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK+1)
#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK+1)
/* for EXT4 extent */
#define EXT4_EXT_MAGIC 0xf30a
#define EXT4_EXTENTS_FLAG 0x00080000
/*
* File types and file modes
*/
#define S_IFDIR 0040000 // Directory
#define S_IFCHR 0020000 // Character device
#define S_IFBLK 0060000 // Block device
#define S_IFREG 0100000 // Regular file
#define S_IFIFO 0010000 // FIFO
#define S_IFLNK 0120000 // Symbolic link
#define S_IFSOCK 0140000 // Socket
#define S_IFSHIFT 12
#define T_IFDIR (S_IFDIR >> S_IFSHIFT)
#define T_IFCHR (S_IFCHR >> S_IFSHIFT)
#define T_IFBLK (S_IFBLK >> S_IFSHIFT)
#define T_IFREG (S_IFREG >> S_IFSHIFT)
#define T_IFIFO (S_IFIFO >> S_IFSHIFT)
#define T_IFLNK (S_IFLNK >> S_IFSHIFT)
#define T_IFSOCK (S_IFSOCK >> S_IFSHIFT)
#define ext2_group_desc_lg2size 5
/*
* super block structure:
* include/linux/ext2_fs.h
*/
struct ext2_super_block {
uint32_t s_inodes_count; /* Inodes count */
uint32_t s_blocks_count; /* Blocks count */
uint32_t s_r_blocks_count; /* Reserved blocks count */
uint32_t s_free_blocks_count; /* Free blocks count */
uint32_t s_free_inodes_count; /* Free inodes count */
uint32_t s_first_data_block; /* First Data Block */
uint32_t s_log_block_size; /* Block size */
uint32_t s_log_frag_size; /* Fragment size */
uint32_t s_blocks_per_group; /* # Blocks per group */
uint32_t s_frags_per_group; /* # Fragments per group */
uint32_t s_inodes_per_group; /* # Inodes per group */
uint32_t s_mtime; /* Mount time */
uint32_t s_wtime; /* Write time */
uint16_t s_mnt_count; /* Mount count */
int16_t s_max_mnt_count; /* Maximal mount count */
uint16_t s_magic; /* Magic signature */
uint16_t s_state; /* File system state */
uint16_t s_errors; /* Behaviour when detecting errors */
uint16_t s_minor_rev_level;
uint32_t s_lastcheck; /* time of last check */
uint32_t s_checkinterval; /* max. time between checks */
uint32_t s_creator_os; /* OS */
uint32_t s_rev_level; /* Revision level */
uint16_t s_def_resuid; /* Default uid for reserved blocks */
uint16_t s_def_resgid; /* Default gid for reserved blocks */
uint32_t s_first_ino; /* First non-reserved inode */
uint16_t s_inode_size; /* size of inode structure */
uint16_t s_block_group_nr; /* block group # of this superblock */
uint32_t s_feature_compat; /* compatible feature set */
uint32_t s_feature_incompat; /* incompatible feature set */
uint32_t s_feature_ro_compat; /* readonly-compatible feature set */
uint8_t s_uuid[16]; /* 128-bit uuid for volume */
char s_volume_name[16]; /* volume name */
char s_last_mounted[64]; /* directory where last mounted */
uint32_t s_algorithm_usage_bitmap; /* For compression */
uint8_t s_prealloc_blocks; /* Nr of blocks to try to preallocate*/
uint8_t s_prealloc_dir_blocks;
uint16_t s_reserved_gdt_blocks; /* Per group desc for online growth */
/*
* Journaling support valid if EXT4_FEATURE_COMPAT_HAS_JOURNAL set.
*/
uint8_t s_journal_uuid[16]; /* uuid of journal superblock */
uint32_t s_journal_inum; /* inode number of journal file */
uint32_t s_journal_dev; /* device number of journal file */
uint32_t s_last_orphan; /* start of list of inodes to delete */
uint32_t s_hash_seed[4]; /* HTREE hash seed */
uint8_t s_def_hash_version; /* Default hash version to use */
uint8_t s_reserved_char_pad;
uint16_t s_desc_size; /* size of group descriptor */
uint32_t s_default_mount_opts;
uint32_t s_first_meta_bg; /* First metablock block group */
uint32_t s_mkfs_time; /* When the filesystem was created */
uint32_t s_jnl_blocks[17]; /* Backup of the journal inode */
/* 64bit support valid if EXT4_FEATURE_COMPAT_64BIT */
uint32_t s_blocks_count_hi; /* Blocks count */
uint32_t s_r_blocks_count_hi; /* Reserved blocks count */
uint32_t s_free_blocks_count_hi;/* Free blocks count */
uint16_t s_min_extra_isize; /* All inodes have at least # bytes */
uint16_t s_want_extra_isize; /* New inodes should reserve # bytes */
uint32_t s_flags; /* Miscellaneous flags */
uint16_t s_raid_stride; /* RAID stride */
uint16_t s_mmp_interval; /* # seconds to wait in MMP checking */
uint64_t s_mmp_block; /* Block for multi-mount protection */
uint32_t s_raid_stripe_width; /* blocks on all data disks (N*stride)*/
uint8_t s_log_groups_per_flex; /* FLEX_BG group size */
uint8_t s_reserved_char_pad2;
uint16_t s_reserved_pad;
uint32_t s_reserved[162]; /* Padding to the end of the block */
};
/*******************************************************************************
#ifndef DEPEND
#if ext2_super_block_size != 1024
#error ext2_super_block definition bogus
#endif
#endif
*******************************************************************************/
/*
* ext2 group desc structure:
*/
struct ext2_group_desc {
uint32_t bg_block_bitmap; /* Blocks bitmap block */
uint32_t bg_inode_bitmap; /* Inodes bitmap block */
uint32_t bg_inode_table; /* Inodes table block */
uint16_t bg_free_blocks_count; /* Free blocks count */
uint16_t bg_free_inodes_count; /* Free inodes count */
uint16_t bg_used_dirs_count; /* Directories count */
uint16_t bg_pad;
uint32_t bg_reserved[3];
};
/*******************************************************************************
#ifndef DEPEND
#if ext2_group_desc_size != 32
#error ext2_group_desc definition bogus
#endif
#endif
*******************************************************************************/
/*
* ext2 inode structure:
*/
struct ext2_inode {
uint16_t i_mode; /* File mode */
uint16_t i_uid; /* Owner Uid */
uint32_t i_size; /* 4: Size in bytes */
uint32_t i_atime; /* Access time */
uint32_t i_ctime; /* 12: Creation time */
uint32_t i_mtime; /* Modification time */
uint32_t i_dtime; /* 20: Deletion Time */
uint16_t i_gid; /* Group Id */
uint16_t i_links_count; /* 24: Links count */
uint32_t i_blocks; /* Blocks count */
uint32_t i_flags; /* 32: File flags */
uint32_t l_i_reserved1;
uint32_t i_block[EXT2_N_BLOCKS]; /* 40: Pointers to blocks */
uint32_t i_version; /* File version (for NFS) */
uint32_t i_file_acl; /* File ACL */
uint32_t i_dir_acl; /* Directory ACL */
uint32_t i_faddr; /* Fragment address */
uint8_t l_i_frag; /* Fragment number */
uint8_t l_i_fsize; /* Fragment size */
uint16_t i_pad1;
uint32_t l_i_reserved2[2];
};
/*******************************************************************************
#ifndef DEPEND
#if ext2_inode_size != 128
#error ext2_inode definition bogus
#endif
#endif
*******************************************************************************/
#define EXT2_NAME_LEN 255
struct ext2_dir_entry {
unsigned int d_inode; /* Inode number */
unsigned short d_rec_len; /* Directory entry length */
unsigned char d_name_len; /* Name length */
unsigned char d_file_type;
char d_name[EXT2_NAME_LEN]; /* File name */
};
/*******************************************************************************
#define EXT2_DIR_PAD 4
#define EXT2_DIR_ROUND (EXT2_DIR_PAD - 1)
#define EXT2_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT2_DIR_ROUND) & \
~EXT2_DIR_ROUND)
*******************************************************************************/
/*
* This is the extent on-disk structure.
* It's used at the bottom of the tree.
*/
struct ext4_extent {
uint32_t ee_block; /* first logical block extent covers */
uint16_t ee_len; /* number of blocks covered by extent */
uint16_t ee_start_hi; /* high 16 bits of physical block */
uint32_t ee_start_lo; /* low 32 bits of physical block */
};
/*
* This is index on-disk structure.
* It's used at all the levels except the bottom.
*/
struct ext4_extent_idx {
uint32_t ei_block; /* index covers logical blocks from 'block' */
uint32_t ei_leaf_lo; /* pointer to the physical block of the next *
* level. leaf or next index could be there */
uint16_t ei_leaf_hi; /* high 16 bits of physical block */
uint16_t ei_unused;
};
/*
* Each block (leaves and indexes), even inode-stored has header.
*/
struct ext4_extent_header {
uint16_t eh_magic; /* probably will support different formats */
uint16_t eh_entries; /* number of valid entries */
uint16_t eh_max; /* capacity of store in entries */
uint16_t eh_depth; /* has tree real underlying blocks? */
uint32_t eh_generation; /* generation of the tree */
};
#define EXT4_FIRST_EXTENT(header) ( (struct ext4_extent *)(header + 1) )
#define EXT4_FIRST_INDEX(header) ( (struct ext4_extent_idx *) (header + 1) )
/*
* The ext2 super block information in memory
*/
struct ext2_sb_info {
uint32_t s_inodes_per_block;/* Number of inodes per block */
uint32_t s_inodes_per_group;/* Number of inodes in a group */
uint32_t s_blocks_per_group;/* Number of blocks in a group */
uint32_t s_desc_per_block; /* Number of group descriptors per block */
uint32_t s_groups_count; /* Number of groups in the fs */
uint32_t s_first_data_block; /* First Data Block */
int s_inode_size;
uint8_t s_uuid[16]; /* 128-bit uuid for volume */
int s_desc_size; /* size of group descriptor */
};
static inline struct ext2_sb_info *EXT2_SB(struct fs_info *fs)
{
return fs->fs_info;
}
#define EXT2_BLOCKS_PER_GROUP(fs) (EXT2_SB(fs)->s_blocks_per_group)
#define EXT2_INODES_PER_GROUP(fs) (EXT2_SB(fs)->s_inodes_per_group)
#define EXT2_INODES_PER_BLOCK(fs) (EXT2_SB(fs)->s_inodes_per_block)
#define EXT2_DESC_PER_BLOCK(fs) (EXT2_SB(fs)->s_desc_per_block)
/*
* ext2 private inode information
*/
struct ext2_pvt_inode {
union {
uint32_t i_block[EXT2_N_BLOCKS];
struct ext4_extent_header i_extent_hdr;
};
};
#define PVT(i) ((struct ext2_pvt_inode *)((i)->pvt))
/*
* functions
*/
block_t ext2_bmap(struct inode *, block_t, size_t *);
int ext2_next_extent(struct inode *, uint32_t);
#endif /* ext2_fs.h */
|