Add more EXT2 data structures.

This commit is contained in:
Enrico Fraccaroli
2021-12-14 01:51:48 +01:00
parent 4715809f96
commit 69f3cc6b88
+171 -16
View File
@@ -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;