diff options
author | Marvin Borner | 2021-09-12 17:00:09 +0200 |
---|---|---|
committer | Marvin Borner | 2021-09-12 17:00:09 +0200 |
commit | 421cebff27c591fe6e7102334e7a02dec197af94 (patch) | |
tree | a3e96386d870b5e5cb2d4bf143581070eac321bf | |
parent | f582a27638479da361c0f2e24501d6662e08b522 (diff) |
Dynamic inode size detection using extensions
-rw-r--r-- | kernel/features/fs.c | 50 | ||||
-rw-r--r-- | kernel/inc/fs.h | 16 |
2 files changed, 49 insertions, 17 deletions
diff --git a/kernel/features/fs.c b/kernel/features/fs.c index 7902d56..145c47a 100644 --- a/kernel/features/fs.c +++ b/kernel/features/fs.c @@ -217,41 +217,63 @@ CLEAR void vfs_install(void) * EXT2 */ -INLINE static void ext2_buffer_read(u32 block, void *buf, struct vfs_dev *dev) +static void ext2_buffer_read(u32 block, void *buf, struct vfs_dev *dev) { dev->read(buf, block * SECTOR_COUNT, SECTOR_COUNT, dev); } -static void ext2_superblock(struct ext2_superblock *buf, struct vfs_dev *dev) +static u8 ext2_verify(struct vfs_dev *dev) { u8 data[BLOCK_SIZE] = { 0 }; ext2_buffer_read(EXT2_SUPER, data, dev); - memcpy(buf, data, sizeof(*buf)); + struct ext2_superblock *sb = (struct ext2_superblock *)data; + return sb->magic == EXT2_MAGIC; +} + +static struct ext2_superblock *ext2_superblock(struct vfs_dev *dev) +{ + struct ext2_superblock *sb; - assert(buf->magic == EXT2_MAGIC); + if (dev->vfs->data) { + sb = dev->vfs->data; + } else { + sb = malloc(BLOCK_SIZE); // TODO: Destroy malloced superblock? + ext2_buffer_read(EXT2_SUPER, sb, dev); + dev->vfs->data = sb; + } + + assert(sb->magic == EXT2_MAGIC); + return sb; +} + +static u32 ext2_inode_size(struct vfs_dev *dev) +{ + struct ext2_superblock *sb = ext2_superblock(dev); + if (sb->major_version == 1) + return sb->inode_size; + return 128; // Or 256? } static struct ext2_inode *ext2_inode(u32 i, struct ext2_inode *in_buf, struct vfs_dev *dev) { - struct ext2_superblock sb = { 0 }; - ext2_superblock(&sb, dev); + struct ext2_superblock *sb = ext2_superblock(dev); + u32 inode_size = ext2_inode_size(dev); u8 data[BLOCK_SIZE] = { 0 }; ext2_buffer_read(EXT2_SUPER + 1, data, dev); struct ext2_bgd *bgd = (struct ext2_bgd *)data; - u32 block_group = (i - 1) / sb.inodes_per_group; - u32 index = (i - 1) % sb.inodes_per_group; - u32 block = (index * EXT2_INODE_SIZE) / BLOCK_SIZE; + u32 block_group = (i - 1) / sb->inodes_per_group; + u32 index = (i - 1) % sb->inodes_per_group; + u32 block = (index * inode_size) / BLOCK_SIZE; bgd += block_group; u8 buf[BLOCK_SIZE] = { 0 }; ext2_buffer_read(bgd->inode_table + block, buf, dev); struct ext2_inode *in = - (struct ext2_inode *)((u32)buf + - (index % (BLOCK_SIZE / EXT2_INODE_SIZE)) * EXT2_INODE_SIZE); + (struct ext2_inode *)((u32)buf + (index % (BLOCK_SIZE / inode_size)) * inode_size); - memcpy(in_buf, in, sizeof(*in_buf)); + memcpy(in_buf, in, inode_size); return in_buf; } @@ -477,9 +499,7 @@ static res ext2_perm(const char *path, enum vfs_perm perm, struct vfs_dev *dev) CLEAR u8 ext2_load(struct vfs_dev *dev) { - struct ext2_superblock sb = { 0 }; - ext2_superblock(&sb, dev); - if (sb.magic != EXT2_MAGIC) + if (!ext2_verify(dev)) return 0; struct vfs *vfs = zalloc(sizeof(*vfs)); diff --git a/kernel/inc/fs.h b/kernel/inc/fs.h index 04d3624..210f0c2 100644 --- a/kernel/inc/fs.h +++ b/kernel/inc/fs.h @@ -112,6 +112,20 @@ struct ext2_superblock { u32 major_version; u16 res_block_uid; u16 res_block_gid; + // From here on only if major_version >=1 + u32 first_inode; + u16 inode_size; + u16 block_group_number; + u32 compatible_features; + u32 incompatible_features; + u32 ro_compatible_features; + u8 uuid[16]; + char volume_name[16]; + char last_mounted_dir[64]; + u32 algorithm_usage; + u8 preallocate_blocks; + u8 preallocate_dir_blocks; + u8 padding[50]; // idk? Doesn't really matter }; struct ext2_bgd { @@ -152,8 +166,6 @@ struct ext2_inode { u8 extension[128]; // TODO: 2038 extension time support }; -#define EXT2_INODE_SIZE (sizeof(struct ext2_inode)) - struct ext2_dirent { u32 inode_num; u16 total_len; |