From c4ab2f6f440f060b1686991b24379a4998aa55a9 Mon Sep 17 00:00:00 2001 From: Benji Dial Date: Thu, 11 Jan 2024 23:53:57 -0500 Subject: file reading, tarfs directory listing --- kernel/fs/tarfs.cpp | 141 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 104 insertions(+), 37 deletions(-) (limited to 'kernel/fs') diff --git a/kernel/fs/tarfs.cpp b/kernel/fs/tarfs.cpp index 7ab0de5..7508c03 100644 --- a/kernel/fs/tarfs.cpp +++ b/kernel/fs/tarfs.cpp @@ -20,11 +20,18 @@ namespace mercury::kernel::fs { if (result != storage::io_result::success) return result; node += ((file_length - 1) / 512 + 2) * 512; - return storage::io_result::success; + uint8_t sector[512]; + result = bd->read_bytes(node, 512, sector); + if (result != storage::io_result::success) + return result; + for (unsigned i = 0; i < 512; ++i) + if (sector[i] != 0) + return storage::io_result::success; + return storage::io_result::out_of_bounds; } storage::io_result tarfs_instance::read_name( - storage::node_id_t node, char *name_buf, size_t &name_len_out + storage::node_id_t node, char *name_buf, unsigned &name_len_out ) { name_len_out = 0; storage::io_result result = bd->read_bytes(node + 345, 155, name_buf); @@ -35,14 +42,14 @@ namespace mercury::kernel::fs { result = bd->read_bytes(node, 100, name_buf + name_len_out); if (result != storage::io_result::success) return result; - size_t new_limit = name_len_out + 100; + unsigned new_limit = name_len_out + 100; while (name_buf[name_len_out] && name_len_out < new_limit) ++name_len_out; return storage::io_result::success; } storage::io_result tarfs_instance::read_num( - uint64_t offset, size_t len, uint64_t &out + uint64_t offset, unsigned len, uint64_t &out ) { //len <= 12 @@ -52,7 +59,7 @@ namespace mercury::kernel::fs { return result; out = 0; - for (size_t i = 0; i < len; ++i) { + for (unsigned i = 0; i < len; ++i) { if (!buffer[i]) return i == 0 ? storage::io_result::fs_corrupt : storage::io_result::success; @@ -74,11 +81,18 @@ namespace mercury::kernel::fs { return _result; \ } +#define RETURN_NOT_SUCCESS(expr) \ + { \ + storage::io_result _result = expr; \ + if (_result != storage::io_result::success) \ + return _result; \ + } + storage::io_result tarfs_instance::get_root_node(storage::node_id_t &out) { out = 0; while (true) { char name_buf[255]; - size_t name_len; + unsigned name_len; RETURN_MAYBE_NOT_FOUND(read_name(out, name_buf, name_len)) if (name_len == 2 && name_buf[0] == '.' && name_buf[1] == '/') return storage::io_result::success; @@ -90,16 +104,28 @@ namespace mercury::kernel::fs { storage::node_id_t &out, storage::directory_iter_t &iter_out ) { + char name_buf[255]; + unsigned name_len; + RETURN_NOT_SUCCESS(read_name(node, name_buf, name_len)) + out = 0; while (true) { - char name_buf[255]; - size_t name_len; - RETURN_MAYBE_NOT_FOUND(read_name(out, name_buf, name_len)) - - //TODO - while (1) - ; + char cand_name_buf[255]; + unsigned cand_name_len; + RETURN_MAYBE_NOT_FOUND(read_name(out, cand_name_buf, cand_name_len)) + + if (cand_name_len > name_len && utility::starts_with( + cand_name_buf, cand_name_len, name_buf, name_len + )) { + const char *rem = cand_name_buf + name_len; + unsigned rem_len = cand_name_len - name_len; + unsigned slash = utility::find(rem, rem_len, '/'); + if (slash == rem_len - 1 || slash == rem_len) { + iter_out = out; + return storage::io_result::success; + } + } RETURN_MAYBE_NOT_FOUND(next_node(out)) @@ -111,18 +137,31 @@ namespace mercury::kernel::fs { storage::node_id_t &out, storage::directory_iter_t &iter ) { + char name_buf[255]; + unsigned name_len; + RETURN_NOT_SUCCESS(read_name(node, name_buf, name_len)) + out = iter; - while (true) { - char name_buf[255]; - size_t name_len; - RETURN_MAYBE_NOT_FOUND(read_name(out, name_buf, name_len)) + RETURN_MAYBE_NOT_FOUND(next_node(out)) - //TODO - //NOTE: before return, do iter = out. - while (1) - ; + while (true) { + char cand_name_buf[255]; + unsigned cand_name_len; + RETURN_MAYBE_NOT_FOUND(read_name(out, cand_name_buf, cand_name_len)) + + if (cand_name_len > name_len && utility::starts_with( + cand_name_buf, cand_name_len, name_buf, name_len + )) { + const char *rem = cand_name_buf + name_len; + unsigned rem_len = cand_name_len - name_len; + unsigned slash = utility::find(rem, rem_len, '/'); + if (slash == rem_len - 1 || slash == rem_len) { + iter = out; + return storage::io_result::success; + } + } RETURN_MAYBE_NOT_FOUND(next_node(out)) @@ -131,17 +170,17 @@ namespace mercury::kernel::fs { } storage::io_result tarfs_instance::get_child(storage::node_id_t node, - storage::node_id_t &out, const char *name, size_t name_len + storage::node_id_t &out, const char *name, unsigned name_len ) { char full_name[255]; - size_t full_name_len; + unsigned full_name_len; RETURN_MAYBE_NOT_FOUND(read_name(node, full_name, full_name_len)) if (full_name_len + name_len > 255) return storage::io_result::not_supported; - for (size_t i = 0; i < name_len; ++i) + for (unsigned i = 0; i < name_len; ++i) full_name[full_name_len + i] = name[i]; full_name_len += name_len; @@ -149,12 +188,12 @@ namespace mercury::kernel::fs { while (true) { char cand_name[255]; - size_t cand_name_len; + unsigned cand_name_len; RETURN_MAYBE_NOT_FOUND(read_name(out, cand_name, cand_name_len)) if (cand_name_len != full_name_len && cand_name_len != full_name_len + 1) goto next_iter; - for (size_t i = 0; i < full_name_len; ++i) + for (unsigned i = 0; i < full_name_len; ++i) if (cand_name[i] != full_name[i]) goto next_iter; if (cand_name_len == full_name_len + 1 && @@ -171,22 +210,33 @@ namespace mercury::kernel::fs { } storage::io_result tarfs_instance::get_name_length( - storage::node_id_t node, size_t &length_out + storage::node_id_t node, unsigned &length_out ) { - //TODO - while (1) - ; + char name_buf[255]; + return get_name(node, name_buf, length_out); } storage::io_result tarfs_instance::get_name( - storage::node_id_t node, char *buffer, size_t &length_out + storage::node_id_t node, char *buffer, unsigned &length_out ) { - //TODO - while (1) - ; + unsigned full_length; + char full_buffer[255]; + RETURN_NOT_SUCCESS(read_name(node, full_buffer, full_length)) + if (full_length == 2) { + //full buffer must be ./ + length_out = 0; + return storage::io_result::success; + } + if (full_buffer[full_length - 1] == '/') + --full_length; + unsigned start = utility::find_last(full_buffer, full_length, '/') + 1; + length_out = full_length - start; + for (unsigned i = 0; i < length_out; ++i) + buffer[i] = full_buffer[start + i]; + return storage::io_result::success; } @@ -194,9 +244,7 @@ namespace mercury::kernel::fs { storage::node_id_t node, uint64_t &length_out ) { - //TODO - while (1) - ; + return read_num(node + 124, 12, length_out); } @@ -225,5 +273,24 @@ namespace mercury::kernel::fs { } + storage::io_result tarfs_instance::resize_file( + storage::node_id_t, uint64_t + ) { + //TODO: support resize if sector count isn't changed? + return storage::io_result::not_supported; + } + + storage::io_result tarfs_instance::read_bytes_from_file( + storage::node_id_t node, uint64_t start, uint64_t count, void *into + ) { + return bd->read_bytes(node + 512 + start, count, into); + } + + storage::io_result tarfs_instance::write_bytes_into_file( + storage::node_id_t, uint64_t, uint64_t, const void * + ) { + //TODO: support this. + return storage::io_result::not_supported; + } } -- cgit v1.2.3