Add more EXT2 data structures.
This commit is contained in:
+171
-16
@@ -22,6 +22,10 @@
|
||||
#include "stdio.h"
|
||||
#include "fcntl.h"
|
||||
|
||||
#define EXT2_SUPERBLOCK_MAGIC 0xEF53
|
||||
#define EXT2_INDIRECT_BLOCKS 12
|
||||
#define EXT2_NAME_LEN 255
|
||||
|
||||
/// @brief The superblock contains all the information about the configuration
|
||||
/// of the filesystem.
|
||||
/// @details The primary copy of the superblock is stored at an offset of 1024
|
||||
@@ -29,61 +33,211 @@
|
||||
/// filesystem. Since it is so important, backup copies of the superblock are
|
||||
/// stored in block groups throughout the filesystem.
|
||||
typedef struct ext2_superblock_t {
|
||||
/// @brief Total number of inodes in file system.
|
||||
uint32_t inodes_count;
|
||||
/// @brief Total number of blocks in file system
|
||||
uint32_t blocks_count;
|
||||
/// @brief Number of blocks reserved for superuser.
|
||||
uint32_t r_blocks_count;
|
||||
/// @brief Total number of unallocated blocks.
|
||||
uint32_t free_blocks_count;
|
||||
/// @brief Total number of unallocated inodes.
|
||||
uint32_t free_inodes_count;
|
||||
/// @brief Block number of the block containing the superblock.
|
||||
uint32_t first_data_block;
|
||||
/// @brief The number to shift 1024 to the left by to obtain the block size
|
||||
/// (log2 (block size) - 10).
|
||||
uint32_t log_block_size;
|
||||
/// @brief The number to shift 1,024 to the left by to obtain the fragment
|
||||
/// size (log2 (fragment size) - 10).
|
||||
uint32_t log_frag_size;
|
||||
/// @brief Number of blocks in each block group.
|
||||
uint32_t blocks_per_group;
|
||||
/// @brief Number of fragments in each block group.
|
||||
uint32_t frags_per_group;
|
||||
/// @brief Number of inodes in each block group.
|
||||
uint32_t inodes_per_group;
|
||||
/// @brief Last mount time (in POSIX time).
|
||||
uint32_t mtime;
|
||||
/// @brief Last written time (in POSIX time).
|
||||
uint32_t wtime;
|
||||
/// @brief Number of times the volume has been mounted since its last
|
||||
/// consistency check (fsck).
|
||||
uint16_t mnt_count;
|
||||
/// @brief Number of mounts allowed before a consistency check (fsck) must
|
||||
/// be done.
|
||||
uint16_t max_mnt_count;
|
||||
/// @brief Ext2 signature (0xef53), used to help confirm the presence of
|
||||
/// Ext2 on a volume.
|
||||
uint16_t magic;
|
||||
/// @brief File system state.
|
||||
uint16_t state;
|
||||
/// @brief What to do when an error is detected.
|
||||
uint16_t errors;
|
||||
/// @brief Minor portion of version (combine with Major portion below to
|
||||
/// construct full version field).
|
||||
uint16_t minor_rev_level;
|
||||
/// @brief POSIX time of last consistency check (fsck).
|
||||
uint32_t lastcheck;
|
||||
/// @brief Interval (in POSIX time) between forced consistency checks
|
||||
/// (fsck).
|
||||
uint32_t checkinterval;
|
||||
/// @brief Operating system ID from which the filesystem on this volume was
|
||||
/// created.
|
||||
uint32_t creator_os;
|
||||
/// @brief Major portion of version (combine with Minor portion above to
|
||||
/// construct full version field).
|
||||
uint32_t rev_level;
|
||||
/// @brief User ID that can use reserved blocks.
|
||||
uint16_t def_resuid;
|
||||
/// @brief Group ID that can use reserved blocks.
|
||||
uint16_t def_resgid;
|
||||
// EXT2_DYNAMIC_REV
|
||||
|
||||
// == Extended Superblock Fields ==========================================
|
||||
/// @brief First non-reserved inode in file system. (In versions < 1.0, this
|
||||
/// is fixed as 11)
|
||||
uint32_t first_ino;
|
||||
/// @brief Size of each inode structure in bytes. (In versions < 1.0, this
|
||||
/// is fixed as 128)
|
||||
uint16_t inode_size;
|
||||
/// @brief Block group that this superblock is part of (if backup copy).
|
||||
uint16_t block_group_nr;
|
||||
/// @brief Optional features present (features that are not required to read
|
||||
/// or write, but usually result in a performance increase).
|
||||
uint32_t feature_compat;
|
||||
/// @brief Required features present (features that are required to be
|
||||
/// supported to read or write)
|
||||
uint32_t feature_incompat;
|
||||
/// @brief Features that if not supported, the volume must be mounted
|
||||
/// read-only).
|
||||
uint32_t feature_ro_compat;
|
||||
/// @brief File system ID (what is output by blkid).
|
||||
uint8_t uuid[16];
|
||||
/// @brief Volume name (C-style string: characters terminated by a 0 byte).
|
||||
uint8_t volume_name[16];
|
||||
/// @brief Path volume was last mounted to (C-style string: characters
|
||||
/// terminated by a 0 byte).
|
||||
uint8_t last_mounted[64];
|
||||
/// @brief Compression algorithms used.
|
||||
uint32_t algo_bitmap;
|
||||
// Performance Hints
|
||||
|
||||
// == Performance Hints ===================================================
|
||||
/// @brief Number of blocks to preallocate for files.
|
||||
uint8_t prealloc_blocks;
|
||||
/// @brief Number of blocks to preallocate for directories.
|
||||
uint8_t prealloc_dir_blocks;
|
||||
uint16_t _padding;
|
||||
// Journaling Support
|
||||
/// @brief (Unused)
|
||||
uint16_t padding0;
|
||||
|
||||
// == Journaling Support ==================================================
|
||||
/// @brief Journal ID
|
||||
uint8_t journal_uuid[16];
|
||||
/// @brief Inode number of journal file.
|
||||
uint32_t journal_inum;
|
||||
/// @brief Device number of journal file.
|
||||
uint32_t jounral_dev;
|
||||
/// @brief Start of list of inodes to delete.
|
||||
uint32_t last_orphan;
|
||||
// Directory Indexing Support
|
||||
|
||||
// == Directory Indexing Support ==========================================
|
||||
/// @brief HTree hash seed.
|
||||
uint32_t hash_seed[4];
|
||||
/// @brief Ddefault hash version to use.
|
||||
uint8_t def_hash_version;
|
||||
uint16_t _padding_a;
|
||||
uint8_t _padding_b;
|
||||
// Other Options
|
||||
/// @brief Padding.
|
||||
uint16_t padding1;
|
||||
/// @brief Padding.
|
||||
uint8_t padding2;
|
||||
|
||||
// == Other Options =======================================================
|
||||
/// @brief The default mount options for the file system.
|
||||
uint32_t default_mount_options;
|
||||
uint32_t first_meta_bg;
|
||||
uint8_t _unused[760];
|
||||
} __attribute__((packed)) ext2_superblock_t;
|
||||
/// @brief The ID of the first meta block group.
|
||||
uint32_t first_meta_block_group_id;
|
||||
/// @brief Reserved.
|
||||
uint8_t reserved[760];
|
||||
} ext2_superblock_t;
|
||||
|
||||
/// @brief
|
||||
typedef struct ext2_group_descriptor_t {
|
||||
/// @brief The block number of the block bitmap for this Block Group
|
||||
uint32_t block_bitmap;
|
||||
/// @brief The block number of the inode allocation bitmap for this Block Group.
|
||||
uint32_t inode_bitmap;
|
||||
/// @brief The block number of the starting block for the inode table for this Block Group.
|
||||
uint32_t inode_table;
|
||||
/// @brief Number of free blocks.
|
||||
uint16_t free_blocks_count;
|
||||
/// @brief Number of free inodes.
|
||||
uint16_t free_inodes_count;
|
||||
/// @brief Number of used directories.
|
||||
uint16_t used_dirs_count;
|
||||
/// @brief Padding.
|
||||
uint16_t pad;
|
||||
/// @brief Reserved.
|
||||
uint32_t reserved[3];
|
||||
} ext2_group_descriptor_t;
|
||||
|
||||
/// @brief The ext2 inode.
|
||||
typedef struct ext2_inode_t {
|
||||
/// @brief File mode
|
||||
uint16_t mode;
|
||||
/// @brief The user identifiers of the owners.
|
||||
uint16_t uid;
|
||||
/// @brief The size of the file in bytes.
|
||||
uint32_t size;
|
||||
/// @brief The time that the inode was accessed.
|
||||
uint32_t atime;
|
||||
/// @brief The time that the inode was created.
|
||||
uint32_t ctime;
|
||||
/// @brief The time that the inode was modified the last time.
|
||||
uint32_t mtime;
|
||||
/// @brief The time that the inode was deleted.
|
||||
uint32_t dtime;
|
||||
/// @brief The group identifiers of the owners.
|
||||
uint16_t gid;
|
||||
/// @brief Number of hard links.
|
||||
uint16_t links_count;
|
||||
/// @brief Blocks count.
|
||||
uint32_t blocks_count;
|
||||
/// @brief File flags.
|
||||
uint32_t flags;
|
||||
/// @brief OS dependant value.
|
||||
uint32_t osd1;
|
||||
union {
|
||||
struct datablocks {
|
||||
uint32_t dir_blocks[EXT2_INDIRECT_BLOCKS];
|
||||
uint32_t indir_block;
|
||||
uint32_t double_indir_block;
|
||||
uint32_t triple_indir_block;
|
||||
} blocks;
|
||||
char symlink[60];
|
||||
} data;
|
||||
/// @brief Value used to indicate the file version (used by NFS).
|
||||
uint32_t generation;
|
||||
/// @brief Value indicating the block number containing the extended attributes.
|
||||
uint32_t file_acl;
|
||||
/// @brief For regular files this 32bit value contains the high 32 bits of the 64bit file size.
|
||||
uint32_t dir_acl;
|
||||
/// @brief Value indicating the location of the file fragment.
|
||||
uint32_t fragment_addr;
|
||||
/// @brief OS dependant structure.
|
||||
uint32_t osd2[3];
|
||||
} ext2_inode_t;
|
||||
|
||||
/// @brief The header of an ext2 directory entry.
|
||||
typedef struct ext2_dirent_t {
|
||||
/// @brief Inode number.
|
||||
uint32_t inode;
|
||||
/// @brief Directory entry length
|
||||
uint16_t direntlen;
|
||||
/// @brief Name length
|
||||
uint8_t namelen;
|
||||
/// @brief File type.
|
||||
uint8_t filetype;
|
||||
/// @brief File name.
|
||||
char name[EXT2_NAME_LEN];
|
||||
} ext2_dirent_t;
|
||||
|
||||
static const char *uuid_to_string(uint8_t uuid[16])
|
||||
{
|
||||
@@ -119,7 +273,7 @@ static void ext2_dump_superblock(ext2_superblock_t *sb)
|
||||
pr_debug("wtime : %s\n", time_to_string(sb->wtime));
|
||||
pr_debug("mnt_count : %d\n", sb->mnt_count);
|
||||
pr_debug("max_mnt_count : %d\n", sb->max_mnt_count);
|
||||
pr_debug("magic : %d\n", sb->magic);
|
||||
pr_debug("magic : 0x%0x\n", sb->magic);
|
||||
pr_debug("state : %d\n", sb->state);
|
||||
pr_debug("errors : %d\n", sb->errors);
|
||||
pr_debug("minor_rev_level : %d\n", sb->minor_rev_level);
|
||||
@@ -141,17 +295,14 @@ static void ext2_dump_superblock(ext2_superblock_t *sb)
|
||||
pr_debug("algo_bitmap : %d\n", sb->algo_bitmap);
|
||||
pr_debug("prealloc_blocks : %d\n", sb->prealloc_blocks);
|
||||
pr_debug("prealloc_dir_blocks : %d\n", sb->prealloc_dir_blocks);
|
||||
pr_debug("_padding : %d\n", sb->_padding);
|
||||
pr_debug("journal_uuid : %s\n", uuid_to_string(sb->journal_uuid));
|
||||
pr_debug("journal_inum : %d\n", sb->journal_inum);
|
||||
pr_debug("jounral_dev : %d\n", sb->jounral_dev);
|
||||
pr_debug("last_orphan : %d\n", sb->last_orphan);
|
||||
pr_debug("hash_seed : %u %u %u %u\n", sb->hash_seed[0], sb->hash_seed[1], sb->hash_seed[2], sb->hash_seed[3]);
|
||||
pr_debug("def_hash_version : %d\n", sb->def_hash_version);
|
||||
pr_debug("_padding_a : %d\n", sb->_padding_a);
|
||||
pr_debug("_padding_b : %d\n", sb->_padding_b);
|
||||
pr_debug("default_mount_options : %d\n", sb->default_mount_options);
|
||||
pr_debug("first_meta_bg : %d\n", sb->first_meta_bg);
|
||||
pr_debug("first_meta_bg : %d\n", sb->first_meta_block_group_id);
|
||||
}
|
||||
|
||||
static vfs_file_t *ext2_mount_callback(const char *path, const char *device)
|
||||
@@ -165,6 +316,10 @@ static vfs_file_t *ext2_mount_callback(const char *path, const char *device)
|
||||
pr_err("Failed to read the superblock table at 1024.\n");
|
||||
return NULL;
|
||||
}
|
||||
if (sb.magic != EXT2_SUPERBLOCK_MAGIC) {
|
||||
pr_err("Wrong magic number, it is not an EXT2 filesystem.\n");
|
||||
return NULL;
|
||||
}
|
||||
ext2_dump_superblock(&sb);
|
||||
}
|
||||
return NULL;
|
||||
|
||||
Reference in New Issue
Block a user