diff options
author | Benji Dial <benji@benjidial.net> | 2024-01-12 20:39:21 -0500 |
---|---|---|
committer | Benji Dial <benji@benjidial.net> | 2024-01-12 20:39:21 -0500 |
commit | 882e74b2191c059a9226cbd8bcb51c97da36247c (patch) | |
tree | 3ecc05882a9097a85749902130849be65911e684 /kernel/storage.cpp | |
parent | c4ab2f6f440f060b1686991b24379a4998aa55a9 (diff) | |
download | hilbert-os-882e74b2191c059a9226cbd8bcb51c97da36247c.tar.gz |
rewrite file system layer
Diffstat (limited to 'kernel/storage.cpp')
-rw-r--r-- | kernel/storage.cpp | 225 |
1 files changed, 18 insertions, 207 deletions
diff --git a/kernel/storage.cpp b/kernel/storage.cpp index 97d89aa..f500f8e 100644 --- a/kernel/storage.cpp +++ b/kernel/storage.cpp @@ -1,49 +1,38 @@ #include <mercury/kernel/storage.hpp> -#define RETURN_IF_NOT_SUCCESS(expr) \ - { \ - io_result _result = expr; \ - if (_result != io_result::success) \ - return _result; \ - } - namespace mercury::kernel::storage { - io_result block_device::load_cache_block(uint64_t i) { + bd_result block_device::load_cache_block(uint64_t i) { if (block_cache_i == i) - return io_result::success; + return bd_result::success; - if (block_cache_dirty) { - RETURN_IF_NOT_SUCCESS( - write_blocks_no_cache(block_cache_i, 1, block_cache)) - block_cache_dirty = false; - } + bd_result result = read_blocks_no_cache(i, 1, block_cache); - io_result result = read_blocks_no_cache(i, 1, block_cache); - - if (result != io_result::success) { + if (result != bd_result::success) { block_cache_i = block_count; return result; } block_cache_i = i; - return io_result::success; + return bd_result::success; } - io_result block_device::read_bytes( + bd_result block_device::read_bytes( uint64_t start, uint64_t count, void *into ) { if (start + count > block_size * block_count) - return io_result::out_of_bounds; + return bd_result::out_of_bounds; uint8_t *into_u8 = (uint8_t *)into; if (start % block_size != 0) { uint64_t prefix_len = block_size - start % block_size; - RETURN_IF_NOT_SUCCESS(load_cache_block(start / block_size)) + bd_result result = load_cache_block(start / block_size); + if (result != bd_result::success) + return result; for (uint64_t i = 0; i < prefix_len; ++i) into_u8[i] = block_cache[start % block_size + i]; into_u8 += prefix_len; @@ -54,202 +43,24 @@ namespace mercury::kernel::storage { uint64_t postfix_start = ((start + count) / block_size) * block_size; if (postfix_start != start) { - RETURN_IF_NOT_SUCCESS(read_blocks_no_cache( - start / block_size, (postfix_start - start) / block_size, into_u8)) + bd_result result = read_blocks_no_cache( + start / block_size, (postfix_start - start) / block_size, into_u8); + if (result != bd_result::success) + return result; count -= postfix_start - start; into_u8 += postfix_start - start; start = postfix_start; } if (count != 0) { - RETURN_IF_NOT_SUCCESS(load_cache_block(start / block_size)) + bd_result result = load_cache_block(start / block_size); + if (result != bd_result::success) + return result; for (uint64_t i = 0; i < count; ++i) into_u8[i] = block_cache[i]; } - return io_result::success; - - } - - utility::list<block_device *> *block_devices; - - static utility::trie<utility::string, block_device *> *mounted_devices; - - void init_storage() { - block_devices = new utility::list<block_device *>(); - mounted_devices = new utility::trie<utility::string, block_device *>(); - } - - void canon_path::parent() { - if (segments.count != 0) - --segments.count; - else if (!absolute) - ++parent_count; - } - - void canon_path::rel(const canon_path &r) { - if (r.absolute) { - segments.count = 0; - absolute = true; - parent_count = 0; - } - for (unsigned i = 0; i < r.parent_count; ++i) - parent(); - for (unsigned i = 0; i < r.segments.count; ++i) - segments.add_end(r.segments.buffer[i]); - } - - void canonize_path(const char *str, unsigned len, canon_path &out) { - - out.absolute = false; - out.parent_count = 0; - out.segments.count = 0; - - if (len == 0) - return; - - if (len == 1 && str[0] == '/') { - out.absolute = true; - return; - } - - if (str[0] == '/') { - out.absolute = true; - ++str; - --len; - } - - while (len != 0) { - - unsigned segment_len = utility::find(str, len, '/'); - unsigned to_skip = segment_len == len ? segment_len : segment_len + 1; - - if (segment_len == 0) - ; - - else if (segment_len == 1 && str[0] == '.') - ; - - else if (segment_len == 2 && str[0] == '.' && str[1] == '.') - out.parent(); - - else { - utility::string segment(str, segment_len); - out.segments.add_end(std::move(segment)); - } - - str += to_skip; - len -= to_skip; - - } - - } - - io_result mount_device( - block_device *bd, const canon_path &path, file_system_mounter mounter - ) { - - if (!path.absolute) - return io_result::bad_path; - - if (mounted_devices->has_key(path.segments)) - return io_result::mount_point_already_used; - - file_system_instance *fs; - RETURN_IF_NOT_SUCCESS(mounter(bd, fs)); - bd->mounted_as = fs; - mounted_devices->try_insert(path.segments, bd); - return io_result::success; - - } - - static io_result symlink_contents( - block_device *bd, node_id_t node, canon_path &out - ) { - //TODO - while (1) - ; - (void)bd; - (void)node; - (void)out; - } - - static io_result resolve_symlinks( - block_device *&bd, node_id_t &node, canon_path &path - ) { - - file_type ft; - RETURN_IF_NOT_SUCCESS(bd->mounted_as->get_file_type(node, ft)) - - if (ft != file_type::symlink) - return io_result::success; - - canon_path contents; - RETURN_IF_NOT_SUCCESS(symlink_contents(bd, node, contents)) - path.parent(); - path.rel(contents); - - return look_up_absolute_path(path, bd, node, true, path); - - } - - io_result look_up_absolute_path(const canon_path &path, - block_device *&bd_out, node_id_t &node_out, bool resolve_final_node, - canon_path &path_without_symlinks_out - ) { - - if (!path.absolute) - return io_result::bad_path; - - unsigned prefix_length; - bd_out = - *mounted_devices->longest_prefix_with_value(path.segments, prefix_length) - .value_here; - RETURN_IF_NOT_SUCCESS(bd_out->mounted_as->get_root_node(node_out)) - - path_without_symlinks_out.absolute = true; - path_without_symlinks_out.parent_count = 0; - path_without_symlinks_out.segments.count = 0; - - for (unsigned i = 0; i < prefix_length; ++i) - path_without_symlinks_out.segments.add_end(path.segments.buffer[i]); - - if (path.segments.count == 0) - goto on_final_node; - - for (unsigned i = prefix_length; i < path.segments.count - 1; ++i) { - - path_without_symlinks_out.segments.add_end(path.segments.buffer[i]); - - RETURN_IF_NOT_SUCCESS(bd_out->mounted_as->get_child(node_out, node_out, - path.segments.buffer[i].buffer, path.segments.buffer[i].count)) - RETURN_IF_NOT_SUCCESS(resolve_symlinks( - bd_out, node_out, path_without_symlinks_out)) - - file_type ft; - RETURN_IF_NOT_SUCCESS(bd_out->mounted_as->get_file_type(node_out, ft)) - - if (ft != file_type::directory) - return io_result::not_a_directory; - - } - - { - //in a block so that compiler sees last_segment - //isn't needed after this and allows the goto above. - const utility::string &last_segment = - path.segments.buffer[path.segments.count - 1]; - path_without_symlinks_out.segments.add_end(last_segment); - RETURN_IF_NOT_SUCCESS(bd_out->mounted_as->get_child( - node_out, node_out, last_segment.buffer, last_segment.count)) - } - - on_final_node: - if (resolve_final_node) - RETURN_IF_NOT_SUCCESS(resolve_symlinks( - bd_out, node_out, path_without_symlinks_out)) - - return io_result::success; + return bd_result::success; } |