From f3a9022897430ff7d9e85135e28fce7078c8ba47 Mon Sep 17 00:00:00 2001 From: Connor Date: Fri, 1 Dec 2023 20:39:12 -0800 Subject: [PATCH] fixed fileio bug --- include/fs.hpp | 2 +- lib/fs/fs_file_io.cpp | 795 ++++++++++++++++++++++-------------------- lib/main.cpp | 229 ++++++++---- 3 files changed, 587 insertions(+), 439 deletions(-) diff --git a/include/fs.hpp b/include/fs.hpp index 39bbc76..3a420aa 100644 --- a/include/fs.hpp +++ b/include/fs.hpp @@ -16,7 +16,7 @@ public: ~Fs(); ssize_t read(INode_Data *inode_data, char buf[], size_t count, size_t offset); - ssize_t write(INode_Data *inode_data, char buf[], size_t count, + ssize_t write(INode_Data *inode_data, const char buf[], size_t count, size_t offset); int truncate(INode_Data *inode_data, size_t length); ssize_t lseek_next_data(INode_Data *inode_data, size_t offset); diff --git a/lib/fs/fs_file_io.cpp b/lib/fs/fs_file_io.cpp index a992f9b..7430804 100644 --- a/lib/fs/fs_file_io.cpp +++ b/lib/fs/fs_file_io.cpp @@ -1,378 +1,419 @@ -#include "fs.hpp" - -class DatablockOperation { -public: - DatablockOperation(int (*_skip)(DatablockOperation *, u_int64_t) = nullptr) - : skip(_skip) {} - char *buf; - size_t count; - size_t offset; - size_t bytes_completed; - Fs *fs; - virtual int operation(u_int64_t block_num, bool *delete_block) = 0; - int (*skip)(DatablockOperation *, u_int64_t); -}; - -int default_skip_func(DatablockOperation *this_op, u_int64_t num_blocks) { - this_op->bytes_completed += (num_blocks * IO_BLOCK_SIZE) - this_op->offset; - this_op->offset = 0; - - if (this_op->bytes_completed >= this_op->count) - return 0; - return 1; -} - -int truncate_skip_func(DatablockOperation *this_op, u_int64_t num_blocks) { - this_op->offset = 0; - return 1; -} - -int Fs::sweep_inode_datablocks(INode_Data *inode_data, - u_int64_t start_block_index, bool allocate, - DatablockOperation *op) { - int result; - - u_int64_t start_index = start_block_index; - for (size_t i = start_index; i < NUMBER_OF_DIRECT_BLOCKS; ++i) { - if ((result = sweep_datablocks(&(inode_data->direct_blocks[i]), 0, 0, - allocate, op)) <= 0) - return result; - start_index = NUMBER_OF_DIRECT_BLOCKS; - } - - start_index -= NUMBER_OF_DIRECT_BLOCKS; - - if (start_index < IO_BLOCK_SIZE) { - if ((result = sweep_datablocks(&(inode_data->single_indirect_block), 1, - start_index, allocate, op)) <= 0) - return result; - start_index = IO_BLOCK_SIZE; - } - - start_index -= IO_BLOCK_SIZE; - - if (start_index < IO_BLOCK_SIZE * IO_BLOCK_SIZE) { - if ((result = sweep_datablocks(&(inode_data->double_indirect_block), 2, - start_index, allocate, op)) <= 0) - return result; - start_index = IO_BLOCK_SIZE * IO_BLOCK_SIZE; - } - - start_index -= IO_BLOCK_SIZE * IO_BLOCK_SIZE; - - if (start_index < (u_int64_t)IO_BLOCK_SIZE * IO_BLOCK_SIZE * IO_BLOCK_SIZE) { - if ((result = sweep_datablocks(&(inode_data->triple_indirect_block), 3, - start_index, allocate, op)) <= 0) - return result; - } - - return 1; -} - -// This can simply be made non recursive by copy pasting - it is just -// written this way as a proof of concept -int Fs::sweep_datablocks(u_int64_t *block_num, int indirect_num, - u_int64_t start_block_index, bool allocate, - DatablockOperation *op) { - char buf[IO_BLOCK_SIZE]; - int err; - int result = -1; - - u_int64_t indirect_block_size; - u_int64_t direct_block_size = 1; - for (int i = 0; i < indirect_num; ++i) { - indirect_block_size = direct_block_size; - direct_block_size *= IO_BLOCK_SIZE; - } - - if ((*block_num) == 0) { - if (allocate) { - if ((err = datablock_manager->new_datablock(block_num)) < 0) - return err; - } else if (op->skip != nullptr) { - return (*(op->skip))(op, direct_block_size); - } - } - - if (indirect_num == 0) { - bool delete_block = false; - if ((result = op->operation(*block_num, &delete_block)) < 0) - return result; - if (delete_block) { - if ((err = datablock_manager->free_datablock(*block_num)) < 0) - return err; - (*block_num) = 0; - } - return result; - } - - if ((*block_num) == 0) { - memset(buf, 0, sizeof(buf)); - } else { - if ((err = disk->read_block(*block_num, buf)) < 0) - return err; - } - - u_int64_t this_layer_start_index = start_block_index / indirect_block_size; - u_int64_t next_layer_start_index = - start_block_index - (indirect_block_size * this_layer_start_index); - - u_int64_t temp; - u_int64_t next_block_num; - bool modified = false; - - for (size_t i = this_layer_start_index * sizeof(u_int64_t); i < IO_BLOCK_SIZE; - i += sizeof(u_int64_t)) { - read_u64(&temp, &buf[i]); - next_block_num = temp; - if ((result = sweep_datablocks(&next_block_num, indirect_num - 1, - next_layer_start_index, allocate, op)) < 0) - return result; - if (next_block_num != temp) { - write_u64(next_block_num, &buf[i]); - modified = true; - } - if (result == 0) - break; - } - - if (modified) { - bool delete_block = true; - for (size_t i = 0; i < IO_BLOCK_SIZE; ++i) - if (buf[i] != 0) { - delete_block = false; - break; - } - if (delete_block) { - if ((err = datablock_manager->free_datablock(*block_num)) < 0) - return err; - (*block_num) = 0; - } else { - if ((err = disk->write_block(*block_num, buf)) < 0) - return err; - } - } - - return result; -} - -class ReadDatablockOperation : public DatablockOperation { -public: - ReadDatablockOperation() : DatablockOperation() {} - int operation(u_int64_t block_num, bool *delete_block) override { - char datablock_buf[IO_BLOCK_SIZE]; - int err; - - // printf("PRINT: (%d) %d %d %d\n", block_num, count, offset, - // bytes_completed); - - size_t read_size = - std::min(IO_BLOCK_SIZE - offset, count - bytes_completed); - - if (block_num != 0) { - if ((err = fs->disk->read_block(block_num, datablock_buf)) < 0) - return err; - - memcpy(&buf[bytes_completed], &datablock_buf[offset], read_size); - } else { - memset(&buf[bytes_completed], 0, read_size); - } - - offset = 0; - bytes_completed += read_size; - - if (bytes_completed >= count) - return 0; - return 1; - } -}; - -class WriteDatablockOperation : public DatablockOperation { -public: - WriteDatablockOperation() : DatablockOperation() {} - int operation(u_int64_t block_num, bool *delete_block) override { - char datablock_buf[IO_BLOCK_SIZE]; - int err; - - size_t write_size = - std::min(IO_BLOCK_SIZE - offset, count - bytes_completed); - - if (write_size < IO_BLOCK_SIZE) - if ((err = fs->disk->read_block(block_num, datablock_buf)) < 0) - return err; - - memcpy(&datablock_buf[offset], &buf[bytes_completed], write_size); - - if ((err = fs->disk->write_block(block_num, datablock_buf)) < 0) - return err; - - offset = 0; - bytes_completed += write_size; - - if (bytes_completed >= count) - return 0; - return 1; - } -}; - -class TruncateDatablockOperation : public DatablockOperation { -public: - TruncateDatablockOperation() : DatablockOperation(truncate_skip_func) {} - int operation(u_int64_t block_num, bool *delete_block) override { - char datablock_buf[IO_BLOCK_SIZE]; - int err; - - if (offset == 0) { - (*delete_block) = true; - return 1; - } - - if ((err = fs->disk->read_block(block_num, datablock_buf)) < 0) - return err; - - memset(&datablock_buf[offset], 0, IO_BLOCK_SIZE - offset); - - if ((err = fs->disk->write_block(block_num, datablock_buf)) < 0) - return err; - - offset = 0; - - return 1; - } -}; - -class LseekNextDataDatablockOperation : public DatablockOperation { -public: - LseekNextDataDatablockOperation() : DatablockOperation(default_skip_func) {} - int operation(u_int64_t block_num, bool *delete_block) override { return 0; } -}; - -class LseekNextHoleDatablockOperation : public DatablockOperation { -public: - LseekNextHoleDatablockOperation() : DatablockOperation() {} - int operation(u_int64_t block_num, bool *delete_block) override { - if (block_num == 0) - return 0; - - bytes_completed += (IO_BLOCK_SIZE)-offset; - offset = 0; - - if (bytes_completed >= count) - return 0; - return 1; - } -}; - -ssize_t Fs::read(INode_Data *inode_data, char buf[], size_t count, - size_t offset) { - int err; - - u_int64_t start_block_index = offset / IO_BLOCK_SIZE; - size_t internal_offset = offset - (start_block_index * IO_BLOCK_SIZE); - - ReadDatablockOperation op = ReadDatablockOperation(); - op.offset = internal_offset; - op.buf = buf; - op.count = std::min(count, inode_data->metadata.size - offset); - op.bytes_completed = 0; - op.fs = this; - - if ((err = sweep_inode_datablocks(inode_data, start_block_index, false, - &op)) != 0) - return err; - - return op.bytes_completed; -} - -ssize_t Fs::write(INode_Data *inode_data, char buf[], size_t count, - size_t offset) { - int err; - - u_int64_t start_block_index = offset / IO_BLOCK_SIZE; - size_t internal_offset = offset - (start_block_index * IO_BLOCK_SIZE); - - WriteDatablockOperation op = WriteDatablockOperation(); - op.offset = internal_offset; - op.buf = buf; - op.count = count; - op.bytes_completed = 0; - op.fs = this; - - if ((err = sweep_inode_datablocks(inode_data, start_block_index, true, - &op)) != 0) - return err; - - inode_data->metadata.size = - std::max(offset + op.bytes_completed, inode_data->metadata.size); - - return op.bytes_completed; -} - -int Fs::truncate(INode_Data *inode_data, size_t length) { - int err; - - u_int64_t start_block_index = length / IO_BLOCK_SIZE; - size_t internal_offset = length - (start_block_index * IO_BLOCK_SIZE); - - TruncateDatablockOperation op = TruncateDatablockOperation(); - op.offset = internal_offset; - op.fs = this; - - if ((err = sweep_inode_datablocks(inode_data, start_block_index, false, - &op)) < 0) - return err; - - inode_data->metadata.size = length; - - return 0; -} - -ssize_t Fs::lseek_next_data(INode_Data *inode_data, size_t offset) { - int err; - - if (offset >= inode_data->metadata.size) - return -1; - - u_int64_t start_block_index = offset / IO_BLOCK_SIZE; - size_t internal_offset = offset - (start_block_index * IO_BLOCK_SIZE); - - LseekNextDataDatablockOperation op = LseekNextDataDatablockOperation(); - op.offset = internal_offset; - op.count = inode_data->metadata.size; - op.bytes_completed = offset; - op.fs = this; - - if ((err = sweep_inode_datablocks(inode_data, start_block_index, false, - &op)) < 0) - return err; - - if (op.bytes_completed >= inode_data->metadata.size) - return -1; - - return op.bytes_completed; -} - -ssize_t Fs::lseek_next_hole(INode_Data *inode_data, size_t offset) { - int err; - - if (offset >= inode_data->metadata.size) - return -1; - - u_int64_t start_block_index = offset / IO_BLOCK_SIZE; - size_t internal_offset = offset - (start_block_index * IO_BLOCK_SIZE); - - LseekNextHoleDatablockOperation op = LseekNextHoleDatablockOperation(); - op.offset = internal_offset; - op.count = inode_data->metadata.size; - op.bytes_completed = offset; - op.fs = this; - - if ((err = sweep_inode_datablocks(inode_data, start_block_index, false, - &op)) < 0) - return err; - - if (op.bytes_completed >= inode_data->metadata.size) - return inode_data->metadata.size; - - return op.bytes_completed; +#include "fs.hpp" + +const u_int64_t INDIRECT_BLOCKS = IO_BLOCK_SIZE / sizeof(u_int64_t); + +class DatablockOperation { +public: + DatablockOperation(int (*_skip)(DatablockOperation *, u_int64_t) = nullptr) + : skip(_skip) {} + size_t count; + size_t offset; + size_t bytes_completed; + Fs *fs; + virtual int operation(u_int64_t block_num, bool *delete_block) = 0; + int (*skip)(DatablockOperation *, u_int64_t); +}; + +int default_skip_func(DatablockOperation *this_op, u_int64_t num_blocks) { + this_op->bytes_completed += (num_blocks * IO_BLOCK_SIZE) - this_op->offset; + this_op->offset = 0; + + if (this_op->bytes_completed >= this_op->count) + return 0; + return 1; +} + +int truncate_skip_func(DatablockOperation *this_op, u_int64_t num_blocks) { + this_op->offset = 0; + return 1; +} + +int Fs::sweep_inode_datablocks(INode_Data *inode_data, + u_int64_t start_block_index, bool allocate, + DatablockOperation *op) { + int result; + + // printf("test2.1\n"); + + u_int64_t start_index = start_block_index; + for (size_t i = start_index; i < NUMBER_OF_DIRECT_BLOCKS; ++i) { + if ((result = sweep_datablocks(&(inode_data->direct_blocks[i]), 0, 0, + allocate, op)) <= 0) + return result; + start_index = NUMBER_OF_DIRECT_BLOCKS; + } + + // printf("test2.2\n"); + + start_index -= NUMBER_OF_DIRECT_BLOCKS; + + if (start_index < INDIRECT_BLOCKS) { + if ((result = sweep_datablocks(&(inode_data->single_indirect_block), 1, + start_index, allocate, op)) <= 0) + return result; + start_index = INDIRECT_BLOCKS; + } + + // printf("test2.3\n"); + + start_index -= INDIRECT_BLOCKS; + + if (start_index < INDIRECT_BLOCKS * INDIRECT_BLOCKS) { + if ((result = sweep_datablocks(&(inode_data->double_indirect_block), 2, + start_index, allocate, op)) <= 0) + return result; + start_index = INDIRECT_BLOCKS * INDIRECT_BLOCKS; + } + + // printf("test2.4\n"); + + start_index -= INDIRECT_BLOCKS * INDIRECT_BLOCKS; + + if (start_index < + (u_int64_t)INDIRECT_BLOCKS * INDIRECT_BLOCKS * INDIRECT_BLOCKS) { + if ((result = sweep_datablocks(&(inode_data->triple_indirect_block), 3, + start_index, allocate, op)) <= 0) + return result; + } + + return 1; +} + +// This can simply be made non recursive by copy pasting - it is just +// written this way as a proof of concept +int Fs::sweep_datablocks(u_int64_t *block_num, int indirect_num, + u_int64_t start_block_index, bool allocate, + DatablockOperation *op) { + char buf[IO_BLOCK_SIZE]; + int err; + int result = -1; + + u_int64_t num_blocks_indirect; + u_int64_t num_blocks = 1; + for (int i = 0; i < indirect_num; ++i) { + num_blocks_indirect = num_blocks; + num_blocks *= INDIRECT_BLOCKS; + } + + // printf("test2.3.1 %d\n", indirect_num); + + if ((*block_num) == 0) { + if (allocate) { + if ((err = datablock_manager->new_datablock(block_num)) < 0) + return err; + } else if (op->skip != nullptr) { + return (*(op->skip))(op, num_blocks); + } + } + + // printf("test2.3.2 %d\n", indirect_num); + + if (indirect_num == 0) { + bool delete_block = false; + if ((result = op->operation(*block_num, &delete_block)) < 0) + return result; + if (delete_block) { + if ((err = datablock_manager->free_datablock(*block_num)) < 0) + return err; + (*block_num) = 0; + } + return result; + } + + // printf("test2.3.3 %d\n", indirect_num); + + if ((*block_num) == 0) { + memset(buf, 0, sizeof(buf)); + } else { + if ((err = disk->read_block(*block_num, buf)) < 0) + return err; + } + + // printf("test2.3.4 %d\n", indirect_num); + + u_int64_t this_layer_start_index = start_block_index / num_blocks_indirect; + u_int64_t next_layer_start_index = + start_block_index - (num_blocks_indirect * this_layer_start_index); + + u_int64_t temp; + u_int64_t next_block_num; + bool modified = false; + + // printf("test2.3.4- %d\n", indirect_num); + + // printf("start_block_index=%d\n", start_block_index); + // printf("this_layer_start_index=%d\n", this_layer_start_index); + // printf("next_layer_start_index=%d\n", next_layer_start_index); + // printf("num_blocks_indirect=%d\n", num_blocks_indirect); + + for (size_t i = this_layer_start_index * sizeof(u_int64_t); i < IO_BLOCK_SIZE; + i += sizeof(u_int64_t)) { + // printf("test2.3.5- %d\n", indirect_num); + read_u64(&temp, &buf[i]); + next_block_num = temp; + if ((result = sweep_datablocks(&next_block_num, indirect_num - 1, + next_layer_start_index, allocate, op)) < 0) + return result; + if (next_block_num != temp) { + write_u64(next_block_num, &buf[i]); + modified = true; + } + if (result == 0) + break; + } + + // printf("test2.3.6 %d\n", indirect_num); + + if (modified) { + bool delete_block = true; + for (size_t i = 0; i < IO_BLOCK_SIZE; ++i) + if (buf[i] != 0) { + delete_block = false; + break; + } + if (delete_block) { + if ((err = datablock_manager->free_datablock(*block_num)) < 0) + return err; + (*block_num) = 0; + } else { + if ((err = disk->write_block(*block_num, buf)) < 0) + return err; + } + } + + // printf("test2.3.7 %d\n", indirect_num); + // printf("test2.3.8 result=%d %d\n", result, indirect_num); + + return result; +} + +class ReadDatablockOperation : public DatablockOperation { +public: + char *buf; + ReadDatablockOperation() : DatablockOperation() {} + int operation(u_int64_t block_num, bool *delete_block) override { + char datablock_buf[IO_BLOCK_SIZE]; + int err; + + // printf("PRINT: (%d) %d %d %d\n", block_num, count, offset, + // bytes_completed); + + size_t read_size = + std::min(IO_BLOCK_SIZE - offset, count - bytes_completed); + + if (block_num != 0) { + if ((err = fs->disk->read_block(block_num, datablock_buf)) < 0) + return err; + + memcpy(&buf[bytes_completed], &datablock_buf[offset], read_size); + } else { + memset(&buf[bytes_completed], 0, read_size); + } + + offset = 0; + bytes_completed += read_size; + + if (bytes_completed >= count) + return 0; + return 1; + } +}; + +class WriteDatablockOperation : public DatablockOperation { +public: + const char *buf; + WriteDatablockOperation() : DatablockOperation() {} + int operation(u_int64_t block_num, bool *delete_block) override { + char datablock_buf[IO_BLOCK_SIZE]; + int err; + + // printf("w: %d\n", bytes_completed); + + size_t write_size = + std::min(IO_BLOCK_SIZE - offset, count - bytes_completed); + + if (write_size < IO_BLOCK_SIZE) + if ((err = fs->disk->read_block(block_num, datablock_buf)) < 0) + return err; + + memcpy(&datablock_buf[offset], &buf[bytes_completed], write_size); + + if ((err = fs->disk->write_block(block_num, datablock_buf)) < 0) + return err; + + offset = 0; + bytes_completed += write_size; + + if (bytes_completed >= count) + return 0; + return 1; + } +}; + +class TruncateDatablockOperation : public DatablockOperation { +public: + TruncateDatablockOperation() : DatablockOperation(truncate_skip_func) {} + int operation(u_int64_t block_num, bool *delete_block) override { + char datablock_buf[IO_BLOCK_SIZE]; + int err; + + if (offset == 0) { + (*delete_block) = true; + return 1; + } + + if ((err = fs->disk->read_block(block_num, datablock_buf)) < 0) + return err; + + memset(&datablock_buf[offset], 0, IO_BLOCK_SIZE - offset); + + if ((err = fs->disk->write_block(block_num, datablock_buf)) < 0) + return err; + + offset = 0; + + return 1; + } +}; + +class LseekNextDataDatablockOperation : public DatablockOperation { +public: + LseekNextDataDatablockOperation() : DatablockOperation(default_skip_func) {} + int operation(u_int64_t block_num, bool *delete_block) override { return 0; } +}; + +class LseekNextHoleDatablockOperation : public DatablockOperation { +public: + LseekNextHoleDatablockOperation() : DatablockOperation() {} + int operation(u_int64_t block_num, bool *delete_block) override { + if (block_num == 0) + return 0; + + bytes_completed += (IO_BLOCK_SIZE)-offset; + offset = 0; + + if (bytes_completed >= count) + return 0; + return 1; + } +}; + +ssize_t Fs::read(INode_Data *inode_data, char buf[], size_t count, + size_t offset) { + int err; + + u_int64_t start_block_index = offset / IO_BLOCK_SIZE; + size_t internal_offset = offset - (start_block_index * IO_BLOCK_SIZE); + + ReadDatablockOperation op = ReadDatablockOperation(); + op.offset = internal_offset; + op.buf = buf; + op.count = std::min(count, inode_data->metadata.size - offset); + op.bytes_completed = 0; + op.fs = this; + + if ((err = sweep_inode_datablocks(inode_data, start_block_index, false, + &op)) != 0) + return err; + + return op.bytes_completed; +} + +ssize_t Fs::write(INode_Data *inode_data, const char buf[], size_t count, + size_t offset) { + int err; + + // printf("test1\n"); + + u_int64_t start_block_index = offset / IO_BLOCK_SIZE; + size_t internal_offset = offset - (start_block_index * IO_BLOCK_SIZE); + + WriteDatablockOperation op = WriteDatablockOperation(); + op.offset = internal_offset; + op.buf = buf; + op.count = count; + op.bytes_completed = 0; + op.fs = this; + + // printf("test2\n"); + + if ((err = sweep_inode_datablocks(inode_data, start_block_index, true, + &op)) != 0) + return err; + + // printf("test3\n"); + + inode_data->metadata.size = + std::max(offset + op.bytes_completed, inode_data->metadata.size); + + return op.bytes_completed; +} + +int Fs::truncate(INode_Data *inode_data, size_t length) { + int err; + + u_int64_t start_block_index = length / IO_BLOCK_SIZE; + size_t internal_offset = length - (start_block_index * IO_BLOCK_SIZE); + + TruncateDatablockOperation op = TruncateDatablockOperation(); + op.offset = internal_offset; + op.fs = this; + + if ((err = sweep_inode_datablocks(inode_data, start_block_index, false, + &op)) < 0) + return err; + + inode_data->metadata.size = length; + + return 0; +} + +ssize_t Fs::lseek_next_data(INode_Data *inode_data, size_t offset) { + int err; + + if (offset >= inode_data->metadata.size) + return -1; + + u_int64_t start_block_index = offset / IO_BLOCK_SIZE; + size_t internal_offset = offset - (start_block_index * IO_BLOCK_SIZE); + + LseekNextDataDatablockOperation op = LseekNextDataDatablockOperation(); + op.offset = internal_offset; + op.count = inode_data->metadata.size; + op.bytes_completed = offset; + op.fs = this; + + if ((err = sweep_inode_datablocks(inode_data, start_block_index, false, + &op)) < 0) + return err; + + if (op.bytes_completed >= inode_data->metadata.size) + return -1; + + return op.bytes_completed; +} + +ssize_t Fs::lseek_next_hole(INode_Data *inode_data, size_t offset) { + int err; + + if (offset >= inode_data->metadata.size) + return -1; + + u_int64_t start_block_index = offset / IO_BLOCK_SIZE; + size_t internal_offset = offset - (start_block_index * IO_BLOCK_SIZE); + + LseekNextHoleDatablockOperation op = LseekNextHoleDatablockOperation(); + op.offset = internal_offset; + op.count = inode_data->metadata.size; + op.bytes_completed = offset; + op.fs = this; + + if ((err = sweep_inode_datablocks(inode_data, start_block_index, false, + &op)) < 0) + return err; + + if (op.bytes_completed >= inode_data->metadata.size) + return inode_data->metadata.size; + + return op.bytes_completed; } \ No newline at end of file diff --git a/lib/main.cpp b/lib/main.cpp index 8b087a5..c77fa38 100644 --- a/lib/main.cpp +++ b/lib/main.cpp @@ -1,6 +1,12 @@ +#define _GNU_SOURCE + #include "fischl.h" #include "fs.hpp" +#include +#include +#include #include +#include int main() { // printf("hello word!"); @@ -36,7 +42,7 @@ int main() { // return 0; - int err; + // int err; // RawDisk *disk = new FakeRawDisk(2048); // Fs *fs = new Fs(disk); @@ -50,7 +56,7 @@ int main() { // disk->print_block(0); // disk->print_block(1); - int BL_SIZE = 4096 / 8; + // int BL_SIZE = 4096 / 8; // u_int64_t buf[BL_SIZE * (56 + 512 + 10)]; @@ -84,58 +90,39 @@ int main() { // printf("%d ", buf2[i]); // printf("\n"); - u_int64_t big_buf[BL_SIZE * 1000]; - char *buf = (char *)big_buf; + // u_int64_t big_buf[BL_SIZE * 1000]; + // char *buf = (char *)big_buf; - int offs = 55 * 4096; + // int offs = 55 * 4096; - RawDisk *disk = new FakeRawDisk(2048); - Fs *fs = new Fs(disk); + // RawDisk *disk = new FakeRawDisk(2048); + // Fs *fs = new Fs(disk); - fs->format(); - disk->print_block(0); - disk->print_block(1); + // fs->format(); + // disk->print_block(0); + // disk->print_block(1); - INode_Data inode_data; - fs->inode_manager->new_inode(1, 2, 3, &inode_data); + // INode_Data inode_data; + // fs->inode_manager->new_inode(1, 2, 3, &inode_data); - disk->print_block(0); - disk->print_block(1); - disk->print_block(1024); + // disk->print_block(0); + // disk->print_block(1); + // disk->print_block(1024); - for (int i = 0; i < BL_SIZE * 3; ++i) - big_buf[i] = 1; + // for (int i = 0; i < BL_SIZE * 3; ++i) + // big_buf[i] = 1; - err = fs->write(&inode_data, buf, 4096 * 3, offs); + // err = fs->write(&inode_data, buf, 4096 * 3, offs); - for (int i = 0; i < BL_SIZE * 3; ++i) - big_buf[i] = 2; + // for (int i = 0; i < BL_SIZE * 3; ++i) + // big_buf[i] = 2; - err = fs->truncate(&inode_data, offs + 4096); - err = fs->write(&inode_data, buf, 4096 * 2, offs + 4096 * 2); - err = fs->truncate(&inode_data, offs + 4096 * 2); + // err = fs->truncate(&inode_data, offs + 4096); + // err = fs->write(&inode_data, buf, 4096 * 2, offs + 4096 * 2); + // err = fs->truncate(&inode_data, offs + 4096 * 2); - fs->inode_manager->save_inode(&inode_data); - printf("Write %d", err); - - disk->print_block(0); - disk->print_block(1); - disk->print_block(1024); - disk->print_block(1025); - disk->print_block(1026); - disk->print_block(1027); - disk->print_block(1028); - disk->print_block(1029); - // disk->print_block(1080); - // disk->print_block(1081); - // disk->print_block(1082); - // disk->print_block(1083); - // disk->print_block(1084); - // disk->print_block(1085); - - // err = fs->truncate(&inode_data, 4096 + 4); // fs->inode_manager->save_inode(&inode_data); - // printf("Truncate %d", err); + // printf("Write %d", err); // disk->print_block(0); // disk->print_block(1); @@ -144,25 +131,145 @@ int main() { // disk->print_block(1026); // disk->print_block(1027); // disk->print_block(1028); + // disk->print_block(1029); + // // disk->print_block(1080); + // // disk->print_block(1081); + // // disk->print_block(1082); + // // disk->print_block(1083); + // // disk->print_block(1084); + // // disk->print_block(1085); - err = fs->lseek_next_hole(&inode_data, offs + 0); - printf("lseek_next_hole (%d): %d\n\n", offs + 0, err); - err = fs->lseek_next_hole(&inode_data, offs + 1); - printf("lseek_next_hole (%d): %d\n\n", offs + 1, err); - err = fs->lseek_next_hole(&inode_data, offs + 4096); - printf("lseek_next_hole (%d): %d\n\n", offs + 4096, err); - err = fs->lseek_next_hole(&inode_data, offs + 4097); - printf("lseek_next_hole (%d): %d\n\n", offs + 4097, err); - err = fs->lseek_next_hole(&inode_data, offs + 8192); - printf("lseek_next_hole (%d): %d\n\n", offs + 8192, err); - err = fs->lseek_next_hole(&inode_data, offs + 8193); - printf("lseek_next_hole (%d): %d\n\n", offs + 8193, err); - err = fs->lseek_next_hole(&inode_data, offs + 12288); - printf("lseek_next_hole (%d): %d\n\n", offs + 12288, err); - err = fs->lseek_next_hole(&inode_data, offs + 12289); - printf("lseek_next_hole (%d): %d\n\n", offs + 12289, err); - err = fs->lseek_next_hole(&inode_data, offs + 100000); - printf("lseek_next_hole (%d): %d\n\n", offs + 100000, err); + // // err = fs->truncate(&inode_data, 4096 + 4); + // // fs->inode_manager->save_inode(&inode_data); + // // printf("Truncate %d", err); + + // // disk->print_block(0); + // // disk->print_block(1); + // // disk->print_block(1024); + // // disk->print_block(1025); + // // disk->print_block(1026); + // // disk->print_block(1027); + // // disk->print_block(1028); + + // err = fs->lseek_next_hole(&inode_data, offs + 0); + // printf("lseek_next_hole (%d): %d\n\n", offs + 0, err); + // err = fs->lseek_next_hole(&inode_data, offs + 1); + // printf("lseek_next_hole (%d): %d\n\n", offs + 1, err); + // err = fs->lseek_next_hole(&inode_data, offs + 4096); + // printf("lseek_next_hole (%d): %d\n\n", offs + 4096, err); + // err = fs->lseek_next_hole(&inode_data, offs + 4097); + // printf("lseek_next_hole (%d): %d\n\n", offs + 4097, err); + // err = fs->lseek_next_hole(&inode_data, offs + 8192); + // printf("lseek_next_hole (%d): %d\n\n", offs + 8192, err); + // err = fs->lseek_next_hole(&inode_data, offs + 8193); + // printf("lseek_next_hole (%d): %d\n\n", offs + 8193, err); + // err = fs->lseek_next_hole(&inode_data, offs + 12288); + // printf("lseek_next_hole (%d): %d\n\n", offs + 12288, err); + // err = fs->lseek_next_hole(&inode_data, offs + 12289); + // printf("lseek_next_hole (%d): %d\n\n", offs + 12289, err); + // err = fs->lseek_next_hole(&inode_data, offs + 100000); + // printf("lseek_next_hole (%d): %d\n\n", offs + 100000, err); + + // RawDisk *disk = new FakeRawDisk(2048); + // Fs *fs = new Fs(disk); + // fs->format(); + + // INode_Data inode_data; + // fs->inode_manager->new_inode(1, 2, 3, &inode_data); + + // char cwd_buf[PATH_MAX]; + // int fd; + + // assert(getcwd(cwd_buf, sizeof(cwd_buf)) != NULL); + + // printf("\n\n("); + + // printf(cwd_buf); + + // printf(")\n\n"); + + // fd = open("/home/connor", O_TMPFILE | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR); + // assert(fd != -1); + + // u_int64_t test_start_range = IO_BLOCK_SIZE * 100; + // u_int64_t test_write_range = IO_BLOCK_SIZE * 50; + // u_int64_t test_read_range = IO_BLOCK_SIZE * 50; + + // char zeros[test_write_range] = {0}; + // char ones[test_write_range]; + // memset(ones, 1, test_write_range); + + // char *write_buf = ones; + // char reference_read_buf[test_read_range]; + // char test_read_buf[test_read_range]; + // size_t offset, count; + // int test_res, ref_res; + + // for (int i = 0; i < 1000; ++i) { + // offset = rand() & test_start_range; + + // switch (rand() % 2) { + // case 0: + // count = rand() & test_write_range; + // write_buf = (write_buf == ones) ? zeros : ones; + // printf("write: %ds count=%d offset=%d\n", write_buf[0], count, offset); + // test_res = fs->write(&inode_data, write_buf, count, offset); + // assert(lseek(fd, offset, SEEK_SET) == offset); + // ref_res = write(fd, write_buf, count); + // break; + // case 1: + // count = rand() & test_read_range; + // printf("read: count=%d offset=%d\n", count, offset); + // test_res = fs->read(&inode_data, test_read_buf, count, offset); + // assert(lseek(fd, offset, SEEK_SET) == offset); + // ref_res = read(fd, reference_read_buf, count); + // bool reads_are_equal = true; + // for (size_t j = 0; j < count; ++j) + // if (test_read_buf[i] != reference_read_buf[i]) { + // reads_are_equal = false; + // break; + // } + // assert(reads_are_equal); + // break; + // } + + // assert(test_res == ref_res); + // } + + RawDisk *disk = new FakeRawDisk(5120); + Fs *fs = new Fs(disk); + fs->format(); + + int buf_size = IO_BLOCK_SIZE * 200; + int loops = 14 * 1024 * 1024 / buf_size; + + char buf[buf_size]; + + memset(buf, 1, sizeof(buf)); + + INode_Data inode_data; + fs->inode_manager->new_inode(1, 2, 3, &inode_data); + + int res; + + for (int j = 0; j < loops; ++j) { + res = fs->write(&inode_data, buf, sizeof(buf), sizeof(buf) * j); + printf("write: %d j=%d\n", res, j); + } + + for (int j = 0; j < loops; ++j) { + + memset(buf, 0, sizeof(buf)); + res = fs->read(&inode_data, buf, sizeof(buf), sizeof(buf) * j); + + printf("read: %d j=%d\n", res, j); + + for (int i = 0; i < sizeof(buf); ++i) + if (buf[1] != 1) { + printf("error: %d\n", i); + return -1; + } + } return 0; } \ No newline at end of file