From d7f8c5e87490537b606ecec69a89bfff21c3bcbb Mon Sep 17 00:00:00 2001 From: Michael Bishop Date: Fri, 20 Aug 2021 20:39:09 -0300 Subject: [PATCH] implement byte-order swaps --- lib/fs/ext2/dir.c | 38 +------------------------------------- lib/fs/ext2/ext2_fs.h | 1 + lib/fs/ext2/ext4_fs.h | 4 ++++ lib/fs/ext2/io.c | 30 +++++++++++++++--------------- 4 files changed, 21 insertions(+), 52 deletions(-) diff --git a/lib/fs/ext2/dir.c b/lib/fs/ext2/dir.c index 2e51fee058..57b4c07f2c 100644 --- a/lib/fs/ext2/dir.c +++ b/lib/fs/ext2/dir.c @@ -21,6 +21,7 @@ struct dircookie { uint cursor; }; +// TODO, move to ext2.c static void ext2_dump_inode(struct ext2_inode *inode) { #if LOCAL_TRACE printf("mode: %d\n", inode->i_mode); @@ -232,43 +233,6 @@ status_t ext2_opendir(fscookie *cookie, const char *name, dircookie **dcookie) { *dcookie = dir; -#if 0 - buf = malloc(EXT2_BLOCK_SIZE(ext2->sb)); - - file_blocknum = 0; - for (;;) { - /* read in the offset */ - err = ext2_read_inode(ext2, &dir_inode, buf, file_blocknum * EXT2_BLOCK_SIZE(ext2->sb), EXT2_BLOCK_SIZE(ext2->sb)); - if (err <= 0) { - free(buf); - return -1; - } - - /* walk through the directory entries, looking for the one that matches */ - struct ext2_dir_entry_2 *ent; - uint pos = 0; - while (pos < EXT2_BLOCK_SIZE(ext2->sb)) { - ent = (struct ext2_dir_entry_2 *)&buf[pos]; - - LTRACEF("ent %d:%d: inode 0x%x, reclen %d, namelen %d\n", - file_blocknum, pos, LE32(ent->inode), LE16(ent->rec_len), ent->name_len/* , ent->name*/); - - /* sanity check the record length */ - if (LE16(ent->rec_len) == 0) - break; - - pos += ROUNDUP(LE16(ent->rec_len), 4); - } - - file_blocknum++; - - /* sanity check the directory. 4MB should be enough */ - if (file_blocknum > 1024) { - free(buf); - return -1; - } - } -#endif return 0; } status_t ext2_readdir(dircookie *cookie, struct dirent *ent_out) { diff --git a/lib/fs/ext2/ext2_fs.h b/lib/fs/ext2/ext2_fs.h index c06f456557..c570a25513 100644 --- a/lib/fs/ext2/ext2_fs.h +++ b/lib/fs/ext2/ext2_fs.h @@ -99,6 +99,7 @@ struct ext2_group_desc { /* * Structure of an inode on the disk + * endian_swap_inode and ext2_load_inode deal with byte-order */ struct ext2_inode { uint16_t i_mode; /* File mode */ diff --git a/lib/fs/ext2/ext4_fs.h b/lib/fs/ext2/ext4_fs.h index 2574fb2a26..6c0a6d7070 100644 --- a/lib/fs/ext2/ext4_fs.h +++ b/lib/fs/ext2/ext4_fs.h @@ -5,6 +5,8 @@ #define RO_COMPAT_EXTRA_ISIZE 0x040 #define RO_COMPAT_METADATA_CSUM 0x400 +// all fields in little-endian, LE16 and LE32 must be used +// TODO? add a variant of endian_swap_inode typedef struct { uint16_t eh_magic; uint16_t eh_entries; @@ -13,6 +15,8 @@ typedef struct { uint32_t eh_generation; } ext4_extent_header; +// all fields in little-endian, LE16 and LE32 must be used +// TODO? add a variant of endian_swap_inode typedef struct { uint32_t ee_block; uint16_t ee_len; diff --git a/lib/fs/ext2/io.c b/lib/fs/ext2/io.c index 1f3e1638b6..5c163d7900 100644 --- a/lib/fs/ext2/io.c +++ b/lib/fs/ext2/io.c @@ -131,32 +131,32 @@ static blocknum_t file_block_to_fs_block(ext2_t *ext2, struct ext2_inode *inode, if (inode->i_flags & 0x80000) { // inode is stored using extents ext4_extent_header *eh = (ext4_extent_header*)&inode->i_block; //printf("its an extent based object\n"); - //printf("eh_magic: 0x%x\n", eh->eh_magic); - //printf("eh_entries: %d\n", eh->eh_entries); - //printf("eh_max: %d\n", eh->eh_max); - //printf("eh_depth: %d\n", eh->eh_depth); - //printf("eh_generation: %d\n", eh->eh_generation); - if (eh->eh_magic != 0xf30a) { + //printf("eh_magic: 0x%x\n", LE16(eh->eh_magic)); + //printf("eh_entries: %d\n", LE16(eh->eh_entries)); + //printf("eh_max: %d\n", LE16(eh->eh_max)); + //printf("eh_depth: %d\n", LE16(eh->eh_depth)); + //printf("eh_generation: %d\n", LE32(eh->eh_generation)); + if (LE16(eh->eh_magic) != 0xf30a) { puts("extent header magic invalid"); return 0; } block = 0; // TODO - if (eh->eh_depth == 0) { + if (eh->LE16(eh_depth) == 0) { ext4_extent *extents = (ext4_extent*)( ((uint32_t)&inode->i_block) + 12); - for (int i=0; ieh_entries; i++) { + for (int i=0; i < LE16(eh->eh_entries); i++) { #if 0 printf("extent %d\n", i); - printf(" ee_block: %d\n", extents[i].ee_block); - printf(" ee_len: %d\n", extents[i].ee_len); - printf(" ee_start_hi: %d\n", extents[i].ee_start_hi); - printf(" ee_start_lo: %d\n", extents[i].ee_start_lo); + printf(" ee_block: %d\n", LE32(extents[i].ee_block)); + printf(" ee_len: %d\n", LE16(extents[i].ee_len)); + printf(" ee_start_hi: %d\n", LE16(extents[i].ee_start_hi)); + printf(" ee_start_lo: %d\n", LE32(extents[i].ee_start_lo)); #endif - if ((fileblock >= extents[i].ee_block) && (fileblock < (extents[i].ee_block + extents[i].ee_len))) { - if (extents[i].ee_start_hi != 0) { + if ((fileblock >= LE32(extents[i].ee_block)) && (fileblock < (LE32(extents[i].ee_block) + LE16(extents[i].ee_len)))) { + if (LE16(extents[i].ee_start_hi) != 0) { puts("unsupported >32bit blocknr"); return 0; } - block = extents[i].ee_start_lo + (fileblock - extents[i].ee_block); + block = LE32(extents[i].ee_start_lo) + (fileblock - LE32(extents[i].ee_block)); } } }