diff options
Diffstat (limited to 'kernel/fs/tarfs.cpp')
-rw-r--r-- | kernel/fs/tarfs.cpp | 296 |
1 files changed, 0 insertions, 296 deletions
diff --git a/kernel/fs/tarfs.cpp b/kernel/fs/tarfs.cpp deleted file mode 100644 index 7508c03..0000000 --- a/kernel/fs/tarfs.cpp +++ /dev/null @@ -1,296 +0,0 @@ -#include <mercury/kernel/fs/tarfs.hpp> - -//in fs::tarfs_instance, storage::node_id_t refers to the number -//of bytes into the block device that the info sector is located - -namespace mercury::kernel::fs { - - storage::io_result tarfs_mounter( - storage::block_device *bd, storage::file_system_instance *&fs_out - ) { - fs_out = new tarfs_instance(bd); - return storage::io_result::success; - } - - tarfs_instance::tarfs_instance(storage::block_device *bd) : bd(bd) {} - - storage::io_result tarfs_instance::next_node(storage::node_id_t &node) { - uint64_t file_length; - storage::io_result result = read_num(node + 124, 12, file_length); - if (result != storage::io_result::success) - return result; - node += ((file_length - 1) / 512 + 2) * 512; - 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, unsigned &name_len_out - ) { - name_len_out = 0; - storage::io_result result = bd->read_bytes(node + 345, 155, name_buf); - if (result != storage::io_result::success) - return result; - while (name_buf[name_len_out] && name_len_out < 155) - ++name_len_out; - result = bd->read_bytes(node, 100, name_buf + name_len_out); - if (result != storage::io_result::success) - return result; - 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, unsigned len, uint64_t &out - ) { - - //len <= 12 - char buffer[12]; - storage::io_result result = bd->read_bytes(offset, len, buffer); - if (result != storage::io_result::success) - return result; - out = 0; - - for (unsigned i = 0; i < len; ++i) { - if (!buffer[i]) - return i == 0 ? storage::io_result::fs_corrupt - : storage::io_result::success; - if (buffer[i] < '0' || buffer[i] > '7') - return storage::io_result::fs_corrupt; - out = out * 8 + buffer[i] - '0'; - } - - return storage::io_result::success; - - } - -#define RETURN_MAYBE_NOT_FOUND(expr) \ - { \ - storage::io_result _result = expr; \ - if (_result == storage::io_result::out_of_bounds) \ - return storage::io_result::not_found; \ - if (_result != storage::io_result::success) \ - 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]; - 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; - RETURN_MAYBE_NOT_FOUND(next_node(out)) - } - } - - storage::io_result tarfs_instance::get_first_child(storage::node_id_t node, - 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 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)) - - } - - } - - storage::io_result tarfs_instance::get_next_child(storage::node_id_t node, - 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; - - RETURN_MAYBE_NOT_FOUND(next_node(out)) - - 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)) - - } - - } - - storage::io_result tarfs_instance::get_child(storage::node_id_t node, - storage::node_id_t &out, const char *name, unsigned name_len - ) { - - char full_name[255]; - 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 (unsigned i = 0; i < name_len; ++i) - full_name[full_name_len + i] = name[i]; - full_name_len += name_len; - - out = 0; - while (true) { - - char cand_name[255]; - 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 (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 && - cand_name[full_name_len] != '/') - goto next_iter; - - return storage::io_result::success; - - next_iter: - RETURN_MAYBE_NOT_FOUND(next_node(out)) - - } - - } - - storage::io_result tarfs_instance::get_name_length( - storage::node_id_t node, unsigned &length_out - ) { - - 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, unsigned &length_out - ) { - - 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; - - } - - storage::io_result tarfs_instance::get_file_length( - storage::node_id_t node, uint64_t &length_out - ) { - - return read_num(node + 124, 12, length_out); - - } - - storage::io_result tarfs_instance::get_file_type( - storage::node_id_t node, storage::file_type &out - ) { - - uint64_t ft; - storage::io_result result = read_num(node + 156, 1, ft); - if (result != storage::io_result::success) - return result; - - switch (ft) { - case 0: - out = storage::file_type::regular_file; - return storage::io_result::success; - case 2: - out = storage::file_type::symlink; - return storage::io_result::success; - case 5: - out = storage::file_type::directory; - return storage::io_result::success; - default: - return storage::io_result::not_supported; - } - - } - - 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; - } - -} |