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 /include/mercury/kernel/storage.hpp | |
parent | c4ab2f6f440f060b1686991b24379a4998aa55a9 (diff) | |
download | hilbert-os-882e74b2191c059a9226cbd8bcb51c97da36247c.tar.gz |
rewrite file system layer
Diffstat (limited to 'include/mercury/kernel/storage.hpp')
-rw-r--r-- | include/mercury/kernel/storage.hpp | 107 |
1 files changed, 39 insertions, 68 deletions
diff --git a/include/mercury/kernel/storage.hpp b/include/mercury/kernel/storage.hpp index 0df0829..61e7d3b 100644 --- a/include/mercury/kernel/storage.hpp +++ b/include/mercury/kernel/storage.hpp @@ -9,22 +9,32 @@ namespace mercury::kernel::storage { typedef uint64_t node_id_t; typedef uint64_t directory_iter_t; - enum file_type { + enum class file_type { regular_file, directory, symlink }; - enum io_result { + enum class bd_result { success, - mount_point_already_used, - not_a_directory, - not_supported, out_of_bounds, + device_error + }; + + enum class fs_result { + success, device_error, - fs_corrupt, - not_found, - bad_path, + fs_corrupt + }; + + struct dir_entry { + utility::string name; + node_id_t node; + file_type type; + //only used if type is regular_file. + uint64_t length; + //only used if type is symlink. + utility::string target; }; class file_system_instance { @@ -32,27 +42,21 @@ namespace mercury::kernel::storage { public: virtual ~file_system_instance() {} - virtual io_result get_root_node(node_id_t &out) = 0; + virtual fs_result get_root_node(node_id_t &out) = 0; - //get_first_child sets iter_out to a "directory iterator" representing the - //first child of this node. get_next_child gets the child after the child - //represented by the value of iter passed in, and changes iter to represent - //that next child. for an empty directory node, get_first_child returns - //io_result::not_found. when iter represents the last child of a node, - //get_next_child also returns io_result::not_found. - virtual io_result get_first_child(node_id_t node, node_id_t &out, directory_iter_t &iter_out) = 0; - virtual io_result get_next_child(node_id_t node, node_id_t &out, directory_iter_t &iter) = 0; - virtual io_result get_child(node_id_t node, node_id_t &out, const char *name, unsigned name_len) = 0; + //it is assumed that this is a directory. sets iter_out + //to a value that can be passed to subsequent calls + //to get_next_child with the same argument for node. + virtual fs_result get_first_child(node_id_t node, std::optional<dir_entry> &out, directory_iter_t &iter_out) = 0; - virtual io_result get_name_length(node_id_t node, unsigned &length_out) = 0; - //buffer is assumed to be long enough - call get_name_length first. - virtual io_result get_name(node_id_t node, char *buffer, unsigned &length_out) = 0; - virtual io_result get_file_length(node_id_t node, uint64_t &length_out) = 0; - virtual io_result get_file_type(node_id_t node, file_type &out) = 0; + //it is assumed that this is a directory. sets iter_out + //to a value that can be passed to subsequent calls + //to get_next_child with the same argument for node. + virtual fs_result get_next_child(node_id_t node, std::optional<dir_entry> &out, directory_iter_t &iter) = 0; - virtual io_result resize_file(node_id_t node, uint64_t new_length) = 0; - virtual io_result read_bytes_from_file(node_id_t node, uint64_t start, uint64_t count, void *into) = 0; - virtual io_result write_bytes_into_file(node_id_t node, uint64_t start, uint64_t count, const void *from) = 0; + //it is assumed that this is a regular file and that + //the region requested is within the bounds of the file. + virtual fs_result read_bytes_from_file(node_id_t node, uint64_t start, uint64_t count, void *into) = 0; }; @@ -61,27 +65,29 @@ namespace mercury::kernel::storage { private: uint8_t *block_cache; uint64_t block_cache_i; - bool block_cache_dirty; - io_result load_cache_block(uint64_t i); + //it is assumed that this block is within the bounds of the device. + bd_result load_cache_block(uint64_t i); protected: - //implemented in driver, bounds not checked - virtual io_result read_blocks_no_cache(uint64_t start, uint64_t count, void *into) = 0; - virtual io_result write_blocks_no_cache(uint64_t start, uint64_t count, const void *from) = 0; + //implemented in driver. it is assumed that the + //blocks are within the bounds of the device. + virtual bd_result read_blocks_no_cache(uint64_t start, uint64_t count, void *into) = 0; //it is assumed that this is only called once, by the driver, after //block_size and block_count have been set, and before read_bytes or - //write_bytes can be called (e.g. in the derived class's constructor) + //write_bytes can be called (e.g. in the derived class's constructor). void allocate_block_cache(); public: //set by storage component file_system_instance *mounted_as; + //set by storage component utility::uuid id; //set by driver uint64_t block_size; + //set by driver uint64_t block_count; virtual ~block_device() { @@ -89,45 +95,10 @@ namespace mercury::kernel::storage { delete block_cache; } - io_result read_bytes(uint64_t start, uint64_t count, void *into); - io_result write_bytes(uint64_t start, uint64_t count, const void *from); + bd_result read_bytes(uint64_t start, uint64_t count, void *into); }; - typedef io_result (*file_system_mounter)(block_device *bd, file_system_instance *&fs_out); - - extern utility::list<block_device *> *block_devices; - - void init_storage(); - - //a canon path contains no . or empty directory names, and - //contains no .. except for at the start of a relative path. - struct canon_path { - - bool absolute; - unsigned parent_count; - utility::vector<utility::string> segments; - - void parent(); - void rel(const canon_path &r); - - utility::string to_string(bool trailing_slash) const; - - }; - - void canonize_path(const char *str, unsigned len, canon_path &out); - - //path must be absolute. - io_result mount_device(block_device *bd, const canon_path &path, file_system_mounter mounter); - - //path must be absolute. symlinks are always resolved on nodes other than the - //final one. they are resolved on the final node if and only if resolve final - //node is set to true. mount points are always traversed, including on the - //final node. this assumes that the path is under some mount point, and the - //same for any symlinks traversed (e.g. / is mounted). - 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); - } #endif |