:: commit ee38f8b4c96cbaf219d63702a6a01e9bbe68ccf6

mintsuki <mintsuki@protonmail.com> — 2020-04-24 12:16

parents: bcfd9e5f91

Improve ext2 inode reading

diff --git a/Makefile b/Makefile
index 5c9adba5..50eeea3e 100644
--- a/Makefile
+++ b/Makefile
@@ -24,16 +24,18 @@ ext2-test: all
 	rm -rf test.img test_image/
 	mkdir test_image
 	dd if=/dev/zero bs=1M count=0 seek=64 of=test.img
-	parted -s test.img mklabel msdos
-	parted -s test.img mkpart primary 1 100%
+	parted -s test.img mklabel gpt
+	parted -s test.img mkpart primary 2048s 6143s
+	parted -s test.img mkpart primary 6144s 131038s
 	sudo losetup -Pf --show test.img > loopback_dev
-	sudo mkfs.ext2 `cat loopback_dev`p1
-	sudo mount `cat loopback_dev`p1 test_image
-	sudo cp test/test.elf test_image
-	sudo cp test/qloader2.cfg test_image
+	sudo mkfs.ext2 `cat loopback_dev`p2
+	sudo mount `cat loopback_dev`p2 test_image
+	sudo mkdir test_image/boot
+	sudo cp test/test.elf test_image/boot/
+	sudo cp test/qloader2.cfg test_image/
 	sync
 	sudo umount test_image/
 	sudo losetup -d `cat loopback_dev`
 	rm -rf test_image loopback_dev
-	./qloader2-install src/qloader2.bin test.img
+	./qloader2-install src/qloader2.bin test.img 2048
 	qemu-system-x86_64 -hda test.img -monitor stdio
diff --git a/qloader2.bin b/qloader2.bin
index a20ea0fc..4f543b22 100644
Binary files a/qloader2.bin and b/qloader2.bin differ
diff --git a/src/fs/ext2fs.c b/src/fs/ext2fs.c
index a44bbc25..54fe75a7 100644
--- a/src/fs/ext2fs.c
+++ b/src/fs/ext2fs.c
@@ -185,6 +185,10 @@ struct ext2fs_dir_entry {
     uint8_t type;       // File type

 } __attribute__((packed));

 

+static int inode_read(void *buf, uint64_t loc, uint64_t count,

+                      uint64_t block_size, struct ext2fs_inode *inode,

+                      uint64_t drive, struct part *part);

+

 // parse an inode given the partition base and inode number

 static int ext2fs_get_inode(struct ext2fs_inode *ret, uint64_t drive, struct part *part, uint64_t inode, struct ext2fs_superblock *sb) {

     if (inode == 0)

@@ -226,16 +230,17 @@ next:
     else

         path++;

 

-    uint64_t offset = current_inode->i_blocks[0] * fd->block_size;

-

-    uint64_t stop = current_inode->i_size + offset;

-    while (offset < stop) {

+    for (uint32_t i = 0; i < current_inode->i_size; ) {

         // preliminary read

-        read_partition(fd->drive, &fd->part, dir, offset, sizeof(struct ext2fs_dir_entry));

+        inode_read(dir, i, sizeof(struct ext2fs_dir_entry),

+                   fd->block_size, current_inode,

+                   fd->drive, &fd->part);

 

         // name read

         char *name = balloc(dir->name_len);

-        read_partition(fd->drive, &fd->part, name, offset + sizeof(struct ext2fs_dir_entry), dir->name_len);

+        inode_read(name, i + sizeof(struct ext2fs_dir_entry), dir->name_len,

+                   fd->block_size, current_inode,

+                   fd->drive, &fd->part);

 

         int r = strncmp(token, name, dir->name_len);

 

@@ -252,7 +257,7 @@ next:
             }

         }

 

-        offset += dir->rec_len;

+        i += dir->rec_len;

     }

 

     brewind(sizeof(struct ext2fs_inode));

@@ -284,54 +289,60 @@ int ext2fs_open(struct ext2fs_file_handle *ret, int drive, int partition, const
 }

 

 int ext2fs_read(struct ext2fs_file_handle *file, void *buf, uint64_t loc, uint64_t count) {

-    // TODO: add support for the indirect block pointers

+    return inode_read(buf, loc, count,

+                      file->block_size, &file->inode,

+                      file->drive, &file->part);

+}

 

+static int inode_read(void *buf, uint64_t loc, uint64_t count,

+                      uint64_t block_size, struct ext2fs_inode *inode,

+                      uint64_t drive, struct part *part) {

     for (uint64_t progress = 0; progress < count;) {

-        uint64_t block = (loc + progress) / file->block_size;

+        uint64_t block = (loc + progress) / block_size;

 

         uint64_t chunk = count - progress;

-        uint64_t offset = (loc + progress) % file->block_size;

-        if (chunk > file->block_size - offset)

-            chunk = file->block_size - offset;

+        uint64_t offset = (loc + progress) % block_size;

+        if (chunk > block_size - offset)

+            chunk = block_size - offset;

 

         uint64_t block_index;

 

         if (block < 12) {

             // Direct block

-            block_index = file->inode.i_blocks[block];

+            block_index = inode->i_blocks[block];

         } else {

             // Indirect block

             block -= 12;

-            if (block * sizeof(uint32_t) >= file->block_size) {

+            if (block * sizeof(uint32_t) >= block_size) {

                 // Double indirect block

-                block -= file->block_size / sizeof(uint32_t);

-                uint32_t index  = block / (file->block_size / sizeof(uint32_t));

-                if (index * sizeof(uint32_t) >= file->block_size) {

+                block -= block_size / sizeof(uint32_t);

+                uint32_t index  = block / (block_size / sizeof(uint32_t));

+                if (index * sizeof(uint32_t) >= block_size) {

                     // Triple indirect block

                     panic("ext2fs: triply indirect blocks unsupported");

                 }

-                uint32_t offset = block % (file->block_size / sizeof(uint32_t));

+                uint32_t offset = block % (block_size / sizeof(uint32_t));

                 uint32_t indirect_block;

                 read_partition(

-                    file->drive, &file->part, &indirect_block,

-                    file->inode.i_blocks[13] * file->block_size + index * sizeof(uint32_t),

+                    drive, part, &indirect_block,

+                    inode->i_blocks[13] * block_size + index * sizeof(uint32_t),

                     sizeof(uint32_t)

                 );

                 read_partition(

-                    file->drive, &file->part, &block_index,

-                    indirect_block * file->block_size + offset * sizeof(uint32_t),

+                    drive, part, &block_index,

+                    indirect_block * block_size + offset * sizeof(uint32_t),

                     sizeof(uint32_t)

                 );

             } else {

                 read_partition(

-                    file->drive, &file->part, &block_index,

-                    file->inode.i_blocks[12] * file->block_size + block * sizeof(uint32_t),

+                    drive, part, &block_index,

+                    inode->i_blocks[12] * block_size + block * sizeof(uint32_t),

                     sizeof(uint32_t)

                 );

             }

         }

 

-        read_partition(file->drive, &file->part, buf + progress, (block_index * file->block_size) + offset, chunk);

+        read_partition(drive, part, buf + progress, (block_index * block_size) + offset, chunk);

 

         progress += chunk;

     }

tab: 248 wrap: offon