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