From 4dcb74d29e56cb7204c1e5f67a6455a2a42943bc Mon Sep 17 00:00:00 2001 From: Connor Date: Wed, 29 Nov 2023 16:42:26 -0800 Subject: [PATCH] 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