From cadf11b857fdf24ce902dead18ef0eaa61340896 Mon Sep 17 00:00:00 2001 From: Connor Date: Tue, 28 Nov 2023 23:44:57 -0800 Subject: [PATCH 1/4] added extra file io operations --- CMakeLists.txt | 2 +- lib/fs/datablock_manager.cpp | 3 +- lib/fs/fs.cpp | 6 +- lib/fs/{fs_read_write.cpp => fs_file_io.cpp} | 196 ++++++++++++++++--- lib/fs/fs_resize.cpp | 67 ------- 5 files changed, 178 insertions(+), 96 deletions(-) rename lib/fs/{fs_read_write.cpp => fs_file_io.cpp} (52%) diff --git a/CMakeLists.txt b/CMakeLists.txt index d438466..bb6a172 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ add_executable(fischl lib/fs/datablock_manager.cpp lib/fs/fs_data_types.cpp lib/fs/fs_resize.cpp - lib/fs/fs_read_write.cpp + lib/fs/fs_file_io.cpp lib/fs/fs.cpp lib/fs/inode_manager.cpp diff --git a/lib/fs/datablock_manager.cpp b/lib/fs/datablock_manager.cpp index e6737d7..e793b29 100644 --- a/lib/fs/datablock_manager.cpp +++ b/lib/fs/datablock_manager.cpp @@ -1,7 +1,7 @@ #include "fs.hpp" DataBlock_Manager::DataBlock_Manager(Fs *fs, u_int64_t block_segment_start, - u_int64_t block_segment_end) + u_int64_t block_segment_end) : fs(fs), block_segment_start(block_segment_start), block_segment_end(block_segment_end) {} @@ -122,6 +122,7 @@ int DataBlock_Manager_Bitmap::format() { char buf[IO_BLOCK_SIZE] = {0}; int err; u_int64_t i = block_segment_start; + write_u64(i, buf); for (; i <= block_segment_end - (2 * bitmap_region_size); i += bitmap_region_size) { write_u64(i + bitmap_region_size, buf); diff --git a/lib/fs/fs.cpp b/lib/fs/fs.cpp index c87ced9..5c5744d 100644 --- a/lib/fs/fs.cpp +++ b/lib/fs/fs.cpp @@ -1,10 +1,12 @@ #include "fs.hpp" Fs::Fs(RawDisk *disk) : disk(disk) { + assert((disk->diskSize / IO_BLOCK_SIZE) > + 2 + NUM_INODE_BLOCKS + DATABLOCKS_PER_BITMAP_BLOCK); superblock = SuperBlock_Data(); inode_manager = new INode_Manager_Freelist(this, 1, 1 + NUM_INODE_BLOCKS); - datablock_manager = - new DataBlock_Manager_Bitmap(this, 1 + NUM_INODE_BLOCKS, NUM_BLOCKS); + datablock_manager = new DataBlock_Manager_Bitmap( + this, 1 + NUM_INODE_BLOCKS, disk->diskSize / IO_BLOCK_SIZE); }; Fs::~Fs() { diff --git a/lib/fs/fs_read_write.cpp b/lib/fs/fs_file_io.cpp similarity index 52% rename from lib/fs/fs_read_write.cpp rename to lib/fs/fs_file_io.cpp index 1aabf8a..57a1de6 100644 --- a/lib/fs/fs_read_write.cpp +++ b/lib/fs/fs_file_io.cpp @@ -6,10 +6,24 @@ public: size_t count; size_t offset; size_t bytes_completed; - RawDisk *disk; - virtual int operation(u_int64_t block_num) = 0; + Fs *fs; + virtual int operation(u_int64_t block_num, bool *delete_block) = 0; + int (*skip)(DatablockOperation *, u_int64_t) = nullptr; }; +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 pass_skip_func(DatablockOperation *this_op, u_int64_t num_blocks) { + return 1; +} + int Fs::sweep_inode_datablocks(INode_Data *inode_data, u_int64_t start_block_index, bool allocate, DatablockOperation *op) { @@ -49,7 +63,7 @@ int Fs::sweep_inode_datablocks(INode_Data *inode_data, return result; } - return -1; + return 1; } // This can simply be made non recursive by copy pasting - it is just @@ -61,12 +75,30 @@ int Fs::sweep_datablocks(u_int64_t *block_num, int indirect_num, int err; int result = -1; - if (allocate && (*block_num) == 0) - if ((err = datablock_manager->new_datablock(block_num)) < 0) - return err; + u_int64_t indirect_block_size = 1; + for (int i = 1; i < indirect_num; ++i) + indirect_block_size *= IO_BLOCK_SIZE; - if (indirect_num == 0) - return op->operation(*block_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, indirect_block_size * IO_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)); @@ -75,10 +107,6 @@ int Fs::sweep_datablocks(u_int64_t *block_num, int indirect_num, return err; } - u_int64_t indirect_block_size = 1; - for (int i = 1; i < indirect_num; ++i) - indirect_block_size *= IO_BLOCK_SIZE; - 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); @@ -102,16 +130,29 @@ int Fs::sweep_datablocks(u_int64_t *block_num, int indirect_num, break; } - if (modified) - if ((err = disk->write_block(*block_num, buf)) < 0) - return err; + 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: - int operation(u_int64_t block_num) override { + int operation(u_int64_t block_num, bool *delete_block) override { char datablock_buf[IO_BLOCK_SIZE]; int err; @@ -122,7 +163,7 @@ public: std::min(IO_BLOCK_SIZE - offset, count - bytes_completed); if (block_num != 0) { - if ((err = disk->read_block(block_num, datablock_buf)) < 0) + if ((err = fs->disk->read_block(block_num, datablock_buf)) < 0) return err; memcpy(&buf[bytes_completed], &datablock_buf[offset], read_size); @@ -141,7 +182,7 @@ public: class WriteDatablockOperation : public DatablockOperation { public: - int operation(u_int64_t block_num) override { + int operation(u_int64_t block_num, bool *delete_block) override { char datablock_buf[IO_BLOCK_SIZE]; int err; @@ -149,12 +190,12 @@ public: std::min(IO_BLOCK_SIZE - offset, count - bytes_completed); if (write_size < IO_BLOCK_SIZE) - if ((err = disk->read_block(block_num, datablock_buf)) < 0) + if ((err = fs->disk->read_block(block_num, datablock_buf)) < 0) return err; memcpy(&datablock_buf[offset], &buf[bytes_completed], write_size); - if ((err = disk->write_block(block_num, datablock_buf)) < 0) + if ((err = fs->disk->write_block(block_num, datablock_buf)) < 0) return err; offset = 0; @@ -166,6 +207,42 @@ public: } }; +class TruncateDatablockOperation : public DatablockOperation { +public: + TruncateDatablockOperation() : skip(pass_skip_func) {} + int operation(u_int64_t block_num, bool *delete_block) override { + if (offset != 0) + return 1; + + offset = 0; + + delete_block = true; + + return 1; + } +}; + +class LseekNextDataDatablockOperation : public DatablockOperation { +public: + LseekNextDataDatablockOperation() : skip(default_skip_func) {} + int operation(u_int64_t block_num, bool *delete_block) override { return 0; } +}; + +class LseekNextHoleDatablockOperation : public DatablockOperation { +public: + 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; @@ -178,10 +255,10 @@ ssize_t Fs::read(INode_Data *inode_data, char buf[], size_t count, op.buf = buf; op.count = std::min(count, inode_data->metadata.size - offset); op.bytes_completed = 0; - op.disk = disk; + op.fs = this; if ((err = sweep_inode_datablocks(inode_data, start_block_index, false, - &op)) < 0) + &op)) != 0) return err; return op.bytes_completed; @@ -199,14 +276,83 @@ ssize_t Fs::write(INode_Data *inode_data, char buf[], size_t count, op.buf = buf; op.count = count; op.bytes_completed = 0; - op.disk = disk; + op.fs = this; - if ((err = sweep_inode_datablocks(inode_data, start_block_index, true, &op)) < - 0) + 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; +} + +int 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; +} + +int 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/fs/fs_resize.cpp b/lib/fs/fs_resize.cpp index 194c064..0fe452a 100644 --- a/lib/fs/fs_resize.cpp +++ b/lib/fs/fs_resize.cpp @@ -1,72 +1,5 @@ #include "fs.hpp" -int Fs::allocate_datablock(INode_Data *inode_data, u_int64_t *datablock_num) { - int result; - - for (size_t i = 0; i < NUMBER_OF_DIRECT_BLOCKS; ++i) { - result = - allocate_indirect(&(inode_data->direct_blocks[i]), 0, datablock_num); - if (result <= 0) - return result; - } - - result = - allocate_indirect(&(inode_data->single_indirect_block), 1, datablock_num); - if (result <= 0) - return result; - - result = - allocate_indirect(&(inode_data->double_indirect_block), 2, datablock_num); - if (result <= 0) - return result; - - result = - allocate_indirect(&(inode_data->triple_indirect_block), 3, datablock_num); - if (result <= 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::allocate_indirect(u_int64_t *storage, int n, u_int64_t *datablock_num) { - char buf[IO_BLOCK_SIZE]; - int result; - - if ((*storage) == 0) { - if ((result = datablock_manager->new_datablock(storage)) < 0) - return result; - if (n == 0) { - (*datablock_num) = (*storage); - return 0; - } - } - - if (n == 0) - return 1; - - u_int64_t temp; - - if ((result = disk->read_block(*storage, buf)) < 0) - return result; - - for (size_t i = 0; i < IO_BLOCK_SIZE; i += sizeof(u_int64_t)) { - read_u64(&temp, &buf[i]); - result = allocate_indirect(&temp, n - 1, datablock_num); - if (result < 0) - return result; - if (result == 0) { - write_u64(temp, &buf[i]); - if ((result = disk->write_block(*storage, buf)) < 0) - return result; - return 0; - } - } - - return 1; -} - int Fs::deallocate_datablock(INode_Data *inode_data, u_int64_t *datablock_num) { int result; From 4dcb74d29e56cb7204c1e5f67a6455a2a42943bc Mon Sep 17 00:00:00 2001 From: Connor Date: Wed, 29 Nov 2023 16:42:26 -0800 Subject: [PATCH 2/4] added extra file io --- CMakeLists.txt | 1 - include/fs.hpp | 23 ++++---- include/fs_constants.hpp | 1 - lib/fs/fs.cpp | 1 + lib/fs/fs_file_io.cpp | 46 ++++++++++----- lib/fs/fs_resize.cpp | 74 ------------------------ lib/main.cpp | 120 ++++++++++++++++++++++++++++++++------- lib/rawdisk.cpp | 10 ++-- test/CMakeLists.txt | 2 +- test/layer1_API.cpp | 65 ++++++++++----------- 10 files changed, 184 insertions(+), 159 deletions(-) delete mode 100644 lib/fs/fs_resize.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index bb6a172..285b085 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,6 @@ add_executable(fischl lib/rawdisk.cpp lib/fs/datablock_manager.cpp lib/fs/fs_data_types.cpp - lib/fs/fs_resize.cpp lib/fs/fs_file_io.cpp lib/fs/fs.cpp lib/fs/inode_manager.cpp diff --git a/include/fs.hpp b/include/fs.hpp index 7a0cd7f..39bbc76 100644 --- a/include/fs.hpp +++ b/include/fs.hpp @@ -15,20 +15,12 @@ public: Fs(RawDisk *disk); ~Fs(); - int allocate_datablock(INode_Data *inode_data, u_int64_t *datablock_num); - int deallocate_datablock(INode_Data *inode_data, u_int64_t *datablock_num); - 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, size_t offset); - - int sweep_inode_datablocks(INode_Data *inode_data, - u_int64_t start_block_index, bool allocate, - DatablockOperation *op); - - int sweep_datablocks(u_int64_t *block_num, int indirect_num, - u_int64_t start_block_index, bool allocate, - DatablockOperation *op); + int truncate(INode_Data *inode_data, size_t length); + ssize_t lseek_next_data(INode_Data *inode_data, size_t offset); + ssize_t lseek_next_hole(INode_Data *inode_data, size_t offset); int format(); @@ -44,8 +36,13 @@ public: int save_free_list_head(u_int64_t new_free_list_head); int save_inode_list_head(u_int64_t new_inode_list_head); - int allocate_indirect(u_int64_t *storage, int n, u_int64_t *datablock_num); - int deallocate_indirect(u_int64_t *storage, int n, u_int64_t *datablock_num); + int sweep_inode_datablocks(INode_Data *inode_data, + u_int64_t start_block_index, bool allocate, + DatablockOperation *op); + + int sweep_datablocks(u_int64_t *block_num, int indirect_num, + u_int64_t start_block_index, bool allocate, + DatablockOperation *op); }; #endif \ No newline at end of file diff --git a/include/fs_constants.hpp b/include/fs_constants.hpp index e74e3ba..ec3ab7b 100644 --- a/include/fs_constants.hpp +++ b/include/fs_constants.hpp @@ -14,7 +14,6 @@ #define IO_BLOCK_SIZE 4096 #define NUM_INODE_BLOCKS 1023 -#define NUM_BLOCKS 2048 #define INODE_SIZE 512 diff --git a/lib/fs/fs.cpp b/lib/fs/fs.cpp index 5c5744d..053d777 100644 --- a/lib/fs/fs.cpp +++ b/lib/fs/fs.cpp @@ -1,4 +1,5 @@ #include "fs.hpp" +#include Fs::Fs(RawDisk *disk) : disk(disk) { assert((disk->diskSize / IO_BLOCK_SIZE) > diff --git a/lib/fs/fs_file_io.cpp b/lib/fs/fs_file_io.cpp index 57a1de6..a992f9b 100644 --- a/lib/fs/fs_file_io.cpp +++ b/lib/fs/fs_file_io.cpp @@ -2,13 +2,15 @@ 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) = nullptr; + int (*skip)(DatablockOperation *, u_int64_t); }; int default_skip_func(DatablockOperation *this_op, u_int64_t num_blocks) { @@ -20,7 +22,8 @@ int default_skip_func(DatablockOperation *this_op, u_int64_t num_blocks) { return 1; } -int pass_skip_func(DatablockOperation *this_op, u_int64_t num_blocks) { +int truncate_skip_func(DatablockOperation *this_op, u_int64_t num_blocks) { + this_op->offset = 0; return 1; } @@ -75,16 +78,19 @@ int Fs::sweep_datablocks(u_int64_t *block_num, int indirect_num, int err; int result = -1; - u_int64_t indirect_block_size = 1; - for (int i = 1; i < indirect_num; ++i) - indirect_block_size *= IO_BLOCK_SIZE; + 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, indirect_block_size * IO_BLOCK_SIZE); + return (*(op->skip))(op, direct_block_size); } } @@ -152,6 +158,7 @@ int Fs::sweep_datablocks(u_int64_t *block_num, int indirect_num, 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; @@ -182,6 +189,7 @@ public: 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; @@ -209,27 +217,39 @@ public: class TruncateDatablockOperation : public DatablockOperation { public: - TruncateDatablockOperation() : skip(pass_skip_func) {} + TruncateDatablockOperation() : DatablockOperation(truncate_skip_func) {} int operation(u_int64_t block_num, bool *delete_block) override { - if (offset != 0) + 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; - delete_block = true; - return 1; } }; class LseekNextDataDatablockOperation : public DatablockOperation { public: - LseekNextDataDatablockOperation() : skip(default_skip_func) {} + 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; @@ -307,7 +327,7 @@ int Fs::truncate(INode_Data *inode_data, size_t length) { return 0; } -int Fs::lseek_next_data(INode_Data *inode_data, size_t offset) { +ssize_t Fs::lseek_next_data(INode_Data *inode_data, size_t offset) { int err; if (offset >= inode_data->metadata.size) @@ -332,7 +352,7 @@ int Fs::lseek_next_data(INode_Data *inode_data, size_t offset) { return op.bytes_completed; } -int Fs::lseek_next_hole(INode_Data *inode_data, size_t offset) { +ssize_t Fs::lseek_next_hole(INode_Data *inode_data, size_t offset) { int err; if (offset >= inode_data->metadata.size) diff --git a/lib/fs/fs_resize.cpp b/lib/fs/fs_resize.cpp deleted file mode 100644 index 0fe452a..0000000 --- a/lib/fs/fs_resize.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "fs.hpp" - -int Fs::deallocate_datablock(INode_Data *inode_data, u_int64_t *datablock_num) { - int result; - - result = deallocate_indirect(&(inode_data->triple_indirect_block), 3, - datablock_num); - if (result <= 0) - return result; - - result = deallocate_indirect(&(inode_data->double_indirect_block), 2, - datablock_num); - if (result <= 0) - return result; - - result = deallocate_indirect(&(inode_data->single_indirect_block), 1, - datablock_num); - if (result <= 0) - return result; - - for (size_t i = NUMBER_OF_DIRECT_BLOCKS - 1; i >= 0; --i) { - result = - deallocate_indirect(&(inode_data->direct_blocks[i]), 0, datablock_num); - if (result <= 0) - return result; - } - - return -1; -} - -int Fs::deallocate_indirect(u_int64_t *storage, int n, - u_int64_t *datablock_num) { - char buf[IO_BLOCK_SIZE]; - int result; - - if (*storage == 0) - return 1; - - if (n == 0) { - u_int64_t temp_datablock_num = (*storage); - if ((result = datablock_manager->free_datablock(*storage)) < 0) - return result; - (*datablock_num) = temp_datablock_num; - (*storage) = 0; - return 0; - } - - u_int64_t temp; - - if ((result = disk->read_block(*storage, buf)) < 0) - return result; - - for (size_t i = IO_BLOCK_SIZE - sizeof(u_int64_t); i >= 0; - i -= sizeof(u_int64_t)) { - read_u64(&temp, &buf[i]); - result = deallocate_indirect(&temp, n - 1, datablock_num); - if (result < 0) - return result; - if (result == 0) { - if (i == 0 && temp == 0) { - if ((result = datablock_manager->free_datablock(*storage)) < 0) - return result; - (*storage) = 0; - } else { - write_u64(temp, &buf[i]); - if ((result = disk->write_block(*storage, buf)) < 0) - return result; - } - return 0; - } - } - - return 1; -} \ No newline at end of file diff --git a/lib/main.cpp b/lib/main.cpp index 049c062..8b087a5 100644 --- a/lib/main.cpp +++ b/lib/main.cpp @@ -34,10 +34,64 @@ int main() { // disk->print_block(1597); + // return 0; + int err; + // RawDisk *disk = new FakeRawDisk(2048); + // Fs *fs = new Fs(disk); + // fs->format(); + // disk->print_block(0); + // disk->print_block(1); + + // INode_Data inode_data; + // fs->inode_manager->new_inode(1, 2, 3, &inode_data); + + // disk->print_block(0); + // disk->print_block(1); + + int BL_SIZE = 4096 / 8; + + // u_int64_t buf[BL_SIZE * (56 + 512 + 10)]; + + // for (int i = 0; i < BL_SIZE * (56 + 512 + 10); ++i) + // buf[i] = (i / BL_SIZE) + 1; + + // err = fs->write(&inode_data, (char *)buf, 4096 * (56 + 3) + 16 + 8, 0); + // fs->inode_manager->save_inode(&inode_data); + + // printf("Write %d", err); + + // disk->print_block(0); + // disk->print_block(1); + // disk->print_block(1025); + // disk->print_block(1026); + // disk->print_block(1027); + // disk->print_block(1080); + // disk->print_block(1081); + // disk->print_block(1082); + // disk->print_block(1083); + // disk->print_block(1084); + // disk->print_block(1085); + + // int N = 5; + + // u_int64_t buf2[4096] = {0}; + // err = fs->read(&inode_data, (char *)buf2, (8 * N), 4096 - 8 - 8); + + // printf("\n\nREAD: %d\n", err); + // for (int i = 0; i < N; ++i) + // printf("%d ", buf2[i]); + // printf("\n"); + + u_int64_t big_buf[BL_SIZE * 1000]; + char *buf = (char *)big_buf; + + int offs = 55 * 4096; + RawDisk *disk = new FakeRawDisk(2048); Fs *fs = new Fs(disk); + fs->format(); disk->print_block(0); disk->print_block(1); @@ -47,40 +101,68 @@ int main() { disk->print_block(0); disk->print_block(1); + disk->print_block(1024); - int BL_SIZE = 4096 / 8; + for (int i = 0; i < BL_SIZE * 3; ++i) + big_buf[i] = 1; - u_int64_t buf[BL_SIZE * (56 + 512 + 10)]; + err = fs->write(&inode_data, buf, 4096 * 3, offs); - for (int i = 0; i < BL_SIZE * (56 + 512 + 10); ++i) - buf[i] = (i / BL_SIZE) + 1; + 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->write(&inode_data, (char *)buf, 4096 * (56 + 3) + 16 + 8, 0); 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(1080); - disk->print_block(1081); - disk->print_block(1082); - disk->print_block(1083); - disk->print_block(1084); - disk->print_block(1085); + 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); - int N = 5; + // err = fs->truncate(&inode_data, 4096 + 4); + // fs->inode_manager->save_inode(&inode_data); + // printf("Truncate %d", err); - u_int64_t buf2[4096] = {0}; - err = fs->read(&inode_data, (char *)buf2, (8 * N), 4096 - 8 - 8); + // 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); - printf("\n\nREAD: %d\n", err); - for (int i = 0; i < N; ++i) - printf("%d ", buf2[i]); - printf("\n"); + 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); return 0; } \ No newline at end of file diff --git a/lib/rawdisk.cpp b/lib/rawdisk.cpp index c0ed0ab..6a1a6e5 100644 --- a/lib/rawdisk.cpp +++ b/lib/rawdisk.cpp @@ -10,12 +10,12 @@ void RawDisk::print_block(u_int64_t block_number) { return; } - printf("\nBlock %llu:\n", block_number); + printf("\nBlock %lu:\n", block_number); for (int i = 0; i < IO_BLOCK_SIZE; i += sizeof(u_int64_t)) { num = 0; for (int j = 0; j < 8; j++) num |= ((u_int64_t)(unsigned char)buf[i + j]) << (8 * j); - printf("%llu ", num); + printf("%lu ", num); if ((i / sizeof(u_int64_t)) % nums_per_line == nums_per_line - 1) printf("\n"); } @@ -47,8 +47,8 @@ RealRawDisk::RealRawDisk(const char *directory) numSectors = diskSize / 512; // Assuming a sector size of 512 bytes printf("====Initializing RawDisk====\n"); - printf("Number of sectors: %llu\n", numSectors); - printf("Disk size (in bytes): %llu\n", diskSize); + printf("Number of sectors: %lu\n", numSectors); + printf("Disk size (in bytes): %lu\n", diskSize); } RealRawDisk::~RealRawDisk() { @@ -101,7 +101,7 @@ FakeRawDisk::FakeRawDisk(u_int64_t num_blocks) { exit(1); } printf("====Initializing FAKE RawDisk====\n"); - printf("FAKE Disk size (in bytes): %llu\n", diskSize); + printf("FAKE Disk size (in bytes): %lu\n", diskSize); perror("!!! USING FAKE RawDisk - THIS IS FOR TESTING ONLY !!!"); } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e92ee57..7e445d8 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -19,7 +19,7 @@ add_executable(${TARGET_LAYER1_API} ../lib/rawdisk.cpp ../lib/fs/datablock_manager.cpp ../lib/fs/fs_data_types.cpp - ../lib/fs/fs_resize.cpp + ../lib/fs/fs_file_io.cpp ../lib/fs/fs.cpp ../lib/fs/inode_manager.cpp ) diff --git a/test/layer1_API.cpp b/test/layer1_API.cpp index b49f0b2..3a5a6f0 100644 --- a/test/layer1_API.cpp +++ b/test/layer1_API.cpp @@ -65,12 +65,12 @@ int main(int argc, char *argv[]) { 1); // the first 8 bytes of 4k I/O block will store // the next address(after 2048*4k I/O block) // test the end of the datablock - H->read_block(NUM_BLOCKS - DATABLOCKS_PER_BITMAP_BLOCK - 1, buffer); - t = 0; - for (int j = 0; j < 8; j++) - t |= ((u_int64_t)(unsigned char)buffer[j]) << (8 * j); + // H->read_block(NUM_BLOCKS - DATABLOCKS_PER_BITMAP_BLOCK - 1, buffer); + // t = 0; + // for (int j = 0; j < 8; j++) + // t |= ((u_int64_t)(unsigned char)buffer[j]) << (8 * j); - assert(t == NUM_BLOCKS - DATABLOCKS_PER_BITMAP_BLOCK - 1); + // assert(t == NUM_BLOCKS - DATABLOCKS_PER_BITMAP_BLOCK - 1); /***************************test inode * de/allocation**********************************/ @@ -108,34 +108,35 @@ int main(int argc, char *argv[]) { // after free the datablock, the program will find the first smallest address // of datablock to give to the inode should test random resize each node, but // should use datablock_free data structure to record - u_int64_t rec_datablock_free[10][3] = {0}; // array version - u_int64_t temp_block_num = 0; - for (int i = 0; i < 10; i++) { - // printf("%dth data block starting addres: ", i); - for (int j = 0; j < 6; j++) { - fs->allocate_datablock(&inode_list[i], &temp_block_num); - // printf("%d," ,inode_inside[i].datablock_allocate(*H)); - } - // printf("\n"); - } - for (int i = 0; i < 10; i++) { - // printf("%dth data block free addres: ", i); - for (int j = 2; j >= 0; j--) { - fs->deallocate_datablock(&inode_list[i], &(rec_datablock_free[i][j])); - // printf("", rec_datablock_free[i][j]); - } - // printf("\n"); - } + // u_int64_t rec_datablock_free[10][3] = {0}; // array version + // u_int64_t temp_block_num = 0; + // for (int i = 0; i < 10; i++) { + // // printf("%dth data block starting addres: ", i); + // for (int j = 0; j < 6; j++) { + // fs->allocate_datablock(&inode_list[i], &temp_block_num); + // // printf("%d," ,inode_inside[i].datablock_allocate(*H)); + // } + // // printf("\n"); + // } + // for (int i = 0; i < 10; i++) { + // // printf("%dth data block free addres: ", i); + // for (int j = 2; j >= 0; j--) { + // fs->deallocate_datablock(&inode_list[i], + // &(rec_datablock_free[i][j])); + // // printf("", rec_datablock_free[i][j]); + // } + // // printf("\n"); + // } - for (int i = 0; i < 10; i++) { - // printf("%dth data block allocate again addres: ", i); - for (int j = 0; j < 3; j++) { - fs->allocate_datablock(&inode_list[i], &temp_block_num); - assert(temp_block_num == rec_datablock_free[i][j]); - // printf("%d," ,inode_inside[i].datablock_allocate(*H)); - } - // printf("\n"); - } + // for (int i = 0; i < 10; i++) { + // // printf("%dth data block allocate again addres: ", i); + // for (int j = 0; j < 3; j++) { + // fs->allocate_datablock(&inode_list[i], &temp_block_num); + // assert(temp_block_num == rec_datablock_free[i][j]); + // // printf("%d," ,inode_inside[i].datablock_allocate(*H)); + // } + // // printf("\n"); + // } // printf("}\n"); delete H; // Delete the RawDisk object From f3a9022897430ff7d9e85135e28fce7078c8ba47 Mon Sep 17 00:00:00 2001 From: Connor Date: Fri, 1 Dec 2023 20:39:12 -0800 Subject: [PATCH 3/4] 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 From 6dc6f36d279723d3c222909ac8ff255f361d552b Mon Sep 17 00:00:00 2001 From: Connor Date: Fri, 1 Dec 2023 23:57:36 -0800 Subject: [PATCH 4/4] quick fix for fileio bug --- lib/fs/datablock_manager.cpp | 4 ++++ lib/fs/fs_file_io.cpp | 42 ++------------------------------ lib/main.cpp | 46 +++++++++++++++++++++++------------- 3 files changed, 35 insertions(+), 57 deletions(-) diff --git a/lib/fs/datablock_manager.cpp b/lib/fs/datablock_manager.cpp index e793b29..192f463 100644 --- a/lib/fs/datablock_manager.cpp +++ b/lib/fs/datablock_manager.cpp @@ -58,6 +58,10 @@ int DataBlock_Manager_Bitmap::new_datablock(u_int64_t *block_num) { if ((err = fs->disk->read_block(bitmap_block_num, bitmap.buf)) < 0) return err; + // if (bitmap.get_next_node() == fs->superblock.free_list_head) + // printf("WARNING: ON LAST BITMAP " + // "BLOCK!\n"); + u_int64_t relative_block_num = bitmap.claim_relative_block(); if (relative_block_num == 0) diff --git a/lib/fs/fs_file_io.cpp b/lib/fs/fs_file_io.cpp index 8905a3d..db8dc37 100644 --- a/lib/fs/fs_file_io.cpp +++ b/lib/fs/fs_file_io.cpp @@ -31,8 +31,6 @@ int Fs::sweep_inode_datablocks(INode_Data *inode_data, 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, @@ -41,8 +39,6 @@ int Fs::sweep_inode_datablocks(INode_Data *inode_data, start_index = NUMBER_OF_DIRECT_BLOCKS; } - // printf("test2.2\n"); - start_index -= NUMBER_OF_DIRECT_BLOCKS; if (start_index < INDIRECT_BLOCKS) { @@ -52,8 +48,6 @@ int Fs::sweep_inode_datablocks(INode_Data *inode_data, start_index = INDIRECT_BLOCKS; } - // printf("test2.3\n"); - start_index -= INDIRECT_BLOCKS; if (start_index < INDIRECT_BLOCKS * INDIRECT_BLOCKS) { @@ -63,8 +57,6 @@ int Fs::sweep_inode_datablocks(INode_Data *inode_data, start_index = INDIRECT_BLOCKS * INDIRECT_BLOCKS; } - // printf("test2.4\n"); - start_index -= INDIRECT_BLOCKS * INDIRECT_BLOCKS; if (start_index < @@ -93,8 +85,6 @@ int Fs::sweep_datablocks(u_int64_t *block_num, int indirect_num, 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) @@ -104,8 +94,6 @@ int Fs::sweep_datablocks(u_int64_t *block_num, int indirect_num, } } - // 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) @@ -118,8 +106,6 @@ int Fs::sweep_datablocks(u_int64_t *block_num, int indirect_num, return result; } - // printf("test2.3.3 %d\n", indirect_num); - if ((*block_num) == 0) { memset(buf, 0, sizeof(buf)); } else { @@ -127,8 +113,6 @@ int Fs::sweep_datablocks(u_int64_t *block_num, int indirect_num, 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); @@ -137,18 +121,11 @@ int Fs::sweep_datablocks(u_int64_t *block_num, int indirect_num, 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; @@ -158,10 +135,9 @@ int Fs::sweep_datablocks(u_int64_t *block_num, int indirect_num, } if (result == 0) break; + next_layer_start_index = 0; } - // printf("test2.3.6 %d\n", indirect_num); - if (modified) { bool delete_block = true; for (size_t i = 0; i < IO_BLOCK_SIZE; ++i) @@ -179,9 +155,6 @@ int Fs::sweep_datablocks(u_int64_t *block_num, int indirect_num, } } - // printf("test2.3.7 %d\n", indirect_num); - // printf("test2.3.8 result=%d %d\n", result, indirect_num); - return result; } @@ -193,9 +166,6 @@ public: 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); @@ -225,8 +195,6 @@ public: 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); @@ -324,8 +292,6 @@ 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); @@ -336,14 +302,10 @@ ssize_t Fs::write(INode_Data *inode_data, const char buf[], size_t 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); diff --git a/lib/main.cpp b/lib/main.cpp index 76875e2..1ac5e82 100644 --- a/lib/main.cpp +++ b/lib/main.cpp @@ -170,7 +170,7 @@ int main(int argc, char *argv[]) { // err = fs->lseek_next_hole(&inode_data, offs + 100000); // printf("lseek_next_hole (%d): %d\n\n", offs + 100000, err); - RawDisk *disk = new FakeRawDisk(5000); + RawDisk *disk = new FakeRawDisk(5120); Fs *fs = new Fs(disk); fs->format(); @@ -188,40 +188,52 @@ int main(int argc, char *argv[]) { u_int64_t test_start_range = IO_BLOCK_SIZE * 3584; u_int64_t test_io_range = IO_BLOCK_SIZE * 100; - char ones[test_io_range]; - memset(ones, 1, test_io_range); - char twos[test_io_range]; - memset(twos, 2, test_io_range); + // char ones[test_io_range]; + // memset(ones, 1, test_io_range); + // char twos[test_io_range]; + // memset(twos, 2, test_io_range); - char *write_buf = ones; + char write_buf[test_io_range]; char reference_read_buf[test_io_range]; char test_read_buf[test_io_range]; size_t offset, count; int test_res, ref_res; bool reads_are_equal; - bool canwrite; + int num; - size_t weird_offset = 6508064; + // size_t weird_offset = 6508064; for (int i = 0; i < 100000; ++i) { offset = rand() % test_start_range; reads_are_equal = true; + num = rand() % 100; + if (num < 49) + num = 0; + else if (num < 99) + num = 1; + else + num = 2; - switch (rand() % 3) { + if (i % 100 == 0) + printf("%d\n", i); + + switch (num) { case 0: count = rand() % test_io_range; - write_buf = (write_buf == ones) ? twos : ones; - if (offset <= weird_offset && (count + offset) > weird_offset) - printf("write: %ds count=%d offset=%d\n", write_buf[0], count, offset); + memset(write_buf, i, count); + // write_buf = (write_buf == ones) ? twos : ones; + // if (offset <= weird_offset && (count + offset) > weird_offset || + // ((char)i == -77)) + // 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_io_range; - if (offset <= weird_offset && (count + offset) > weird_offset) - printf("read: count=%d offset=%d\n", count, offset); + // if (offset <= weird_offset && (count + offset) > weird_offset) + // 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); @@ -232,14 +244,14 @@ int main(int argc, char *argv[]) { } break; case 2: - if (offset <= weird_offset) - printf("truncate: length=%d\n", offset); + // if (offset <= weird_offset) + // printf("truncate: length=%d\n", offset); test_res = fs->truncate(&inode_data, offset); ref_res = ftruncate(fd, offset); break; } - // printf("test_res=%d, ref_res=%d\n", test_res, ref_res); + // printf("test_res=%d, ref_res=%d\n", test_res, ref_res); assert(test_res == ref_res); if (!reads_are_equal && count > 0) {