summaryrefslogtreecommitdiff
path: root/kernel/storage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/storage.cpp')
-rw-r--r--kernel/storage.cpp225
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;
}