#ifndef MERCURY_KERNEL_STORAGE_HPP #define MERCURY_KERNEL_STORAGE_HPP #include #include namespace mercury::kernel::storage { typedef uint64_t node_id_t; typedef uint64_t directory_iter_t; enum class file_type { regular_file, directory, symlink }; enum class bd_result { success, out_of_bounds, device_error }; enum class fs_result { success, device_error, 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 { public: virtual ~file_system_instance() {} virtual fs_result get_root_node(node_id_t &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_first_child(node_id_t node, std::optional &out, directory_iter_t &iter_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 &out, directory_iter_t &iter) = 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; }; class block_device { private: uint8_t *block_cache; uint64_t block_cache_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. 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). 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() { if (block_cache) delete block_cache; } bd_result read_bytes(uint64_t start, uint64_t count, void *into); }; } #endif