:: commit 54074f2a9751ff2777608083d95d5d6aa8b92820

mintsuki <mintsuki@protonmail.com> — 2020-01-22 02:11

parents: 85d6152025

Bug fixes in echfs driver, add 64 bit integer print formats

diff --git a/src/fs/echfs.c b/src/fs/echfs.c
index d685f90d..42611eb0 100644
--- a/src/fs/echfs.c
+++ b/src/fs/echfs.c
@@ -2,6 +2,8 @@
 #include <stdint.h>
 #include <lib/libc.h>
 #include <lib/print.h>
+#include <drivers/disk.h>
+#include <lib/types.h>
 
 struct echfs_identity_table {
     uint8_t jmp[4];
@@ -30,36 +32,39 @@ struct echfs_dir_entry {
 #define FILE_TYPE    0
 
 int load_echfs_file(int disk, int partition, void *buffer, const char *filename) {
-    // Read the S U P E R B L O C K.
     struct echfs_identity_table id_table;
     read_partition(disk, partition, &id_table, 0, sizeof(struct echfs_identity_table));
 
-    // Check the signature.
     if (strncmp(id_table.signature, "_ECH_FS_", 8)) {
+        print("echfs: signature invalid\n", filename);
         return -1;
     }
 
-    // Variables from the table.
-    const uint64_t block_size  = id_table.block_size;
-    const uint64_t block_count = id_table.block_count;
-    const uint64_t dir_length  = id_table.dir_length;
-
-    // Calculate the offset, jumping the Allocation table and reserved blocks.
-    int offset = (16 * block_size) + (block_count * sizeof(uint64_t) / block_size);
+    const uint64_t block_size         = id_table.block_size;
+    const uint64_t block_count        = id_table.block_count;
+    const uint64_t dir_length         = id_table.dir_length * block_size;
+    const uint64_t alloc_table_size   = DIV_ROUNDUP(block_count * sizeof(uint64_t), block_size) * block_size;
+    const uint64_t alloc_table_offset = 16 * block_size;
+    const uint64_t dir_offset         = alloc_table_offset + alloc_table_size;
 
     // Find the file in the root dir.
     struct echfs_dir_entry entry;
-    for (int i = offset; i < dir_length * block_size; i += sizeof(struct echfs_dir_entry)) {
-        read_partition(disk, partition, &entry, i, sizeof(struct echfs_dir_entry));
+    for (uint64_t i = 0; i < dir_length; i += sizeof(struct echfs_dir_entry)) {
+        read_partition(disk, partition, &entry, i + dir_offset, sizeof(struct echfs_dir_entry));
+
+        if (!entry.parent_id) {
+            break;
+        }
 
         if (!strcmp(filename, entry.name) && entry.parent_id == ROOT_DIR_ID && entry.type == FILE_TYPE) {
-            goto FOUND;
+            goto found;
         }
     }
 
+    print("echfs: file %s not found\n", filename);
     return -1;
 
-    FOUND:;
+found:;
     // Load the file.
     for (uint64_t i = entry.payload; i != END_OF_CHAIN;) {
         // Read block.
@@ -67,7 +72,7 @@ int load_echfs_file(int disk, int partition, void *buffer, const char *filename)
         buffer += block_size;
 
         // Read the next block.
-        read_partition(disk, partition, &i, (16 * block_size) + i * sizeof(uint64_t), sizeof(uint64_t));
+        read_partition(disk, partition, &i, alloc_table_offset + i * sizeof(uint64_t), sizeof(uint64_t));
     }
 
     return 0;
diff --git a/src/lib/print.c b/src/lib/print.c
index c8b955aa..0c48f439 100644
--- a/src/lib/print.c
+++ b/src/lib/print.c
@@ -46,9 +46,9 @@ static void prn_char(char *print_buf, size_t *print_buf_i, char c) {
     return;
 }
 
-static void prn_i(char *print_buf, size_t *print_buf_i, int32_t x) {
+static void prn_i(char *print_buf, size_t *print_buf_i, int64_t x) {
     int i;
-    char buf[12] = {0};
+    char buf[20] = {0};
 
     if (!x) {
         prn_char(print_buf, print_buf_i, '0');
@@ -58,7 +58,7 @@ static void prn_i(char *print_buf, size_t *print_buf_i, int32_t x) {
     int sign = x < 0;
     if (sign) x = -x;
 
-    for (i = 10; x; i--) {
+    for (i = 18; x; i--) {
         buf[i] = (x % 10) + 0x30;
         x = x / 10;
     }
@@ -72,16 +72,16 @@ static void prn_i(char *print_buf, size_t *print_buf_i, int32_t x) {
     return;
 }
 
-static void prn_ui(char *print_buf, size_t *print_buf_i, uint32_t x) {
+static void prn_ui(char *print_buf, size_t *print_buf_i, uint64_t x) {
     int i;
-    char buf[11] = {0};
+    char buf[21] = {0};
 
     if (!x) {
         prn_char(print_buf, print_buf_i, '0');
         return;
     }
 
-    for (i = 9; x; i--) {
+    for (i = 19; x; i--) {
         buf[i] = (x % 10) + 0x30;
         x = x / 10;
     }
@@ -92,16 +92,16 @@ static void prn_ui(char *print_buf, size_t *print_buf_i, uint32_t x) {
     return;
 }
 
-static void prn_x(char *print_buf, size_t *print_buf_i, uint32_t x) {
+static void prn_x(char *print_buf, size_t *print_buf_i, uint64_t x) {
     int i;
-    char buf[9] = {0};
+    char buf[17] = {0};
 
     if (!x) {
         prn_str(print_buf, print_buf_i, "0x0");
         return;
     }
 
-    for (i = 7; x; i--) {
+    for (i = 15; x; i--) {
         buf[i] = base_digits[(x % 16)];
         x = x / 16;
     }
@@ -145,13 +145,22 @@ void print(const char *fmt, ...) {
                     prn_nstr(print_buf, &print_buf_i, str, str_len); }
                 break;
             case 'd':
-                prn_i(print_buf, &print_buf_i, va_arg(args, int32_t));
+                prn_i(print_buf, &print_buf_i, (int64_t)va_arg(args, int32_t));
                 break;
             case 'u':
-                prn_ui(print_buf, &print_buf_i, va_arg(args, uint32_t));
+                prn_ui(print_buf, &print_buf_i, (uint64_t)va_arg(args, uint32_t));
                 break;
             case 'x':
-                prn_x(print_buf, &print_buf_i, va_arg(args, uint32_t));
+                prn_x(print_buf, &print_buf_i, (uint64_t)va_arg(args, uint32_t));
+                break;
+            case 'D':
+                prn_i(print_buf, &print_buf_i, va_arg(args, int64_t));
+                break;
+            case 'U':
+                prn_ui(print_buf, &print_buf_i, va_arg(args, uint64_t));
+                break;
+            case 'X':
+                prn_x(print_buf, &print_buf_i, va_arg(args, uint64_t));
                 break;
             case 'c': {
                 char c = (char)va_arg(args, int);
diff --git a/src/lib/types.h b/src/lib/types.h
index b186589e..a7a6b784 100644
--- a/src/lib/types.h
+++ b/src/lib/types.h
@@ -3,4 +3,6 @@
 
 typedef void *symbol[];
 
+#define DIV_ROUNDUP(a, b) (((a) + ((b) - 1)) / (b))
+
 #endif
tab: 248 wrap: offon