From 9ed5936762e85ed1f5a2e9a7b4d81d68b36b81b6 Mon Sep 17 00:00:00 2001 From: Connor Date: Fri, 17 Nov 2023 01:33:19 -0800 Subject: [PATCH] half of tests added --- CMakeLists.txt | 4 +- include/fs.hpp | 8 +- lib/fs/datablock_manager.cpp | 270 +++++++++++++++++------------------ lib/fs/fs_resize.cpp | 64 +++++---- lib/fs/inode_manager.cpp | 266 +++++++++++++++++----------------- lib/main.cpp | 5 +- lib/rawdisk.cpp | 4 +- test/CMakeLists.txt | 23 ++- test/layer0.cpp | 43 +++--- test/layer1_API.cpp | 228 ++++++++++++++++------------- test/layer1_test1.cpp | 243 ++++++++++++++++--------------- 11 files changed, 614 insertions(+), 544 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f7455c4..684640d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,5 +21,5 @@ add_executable(fischl ) -#enable_testing() -#add_subdirectory(test) \ No newline at end of file +enable_testing() +add_subdirectory(test) \ No newline at end of file diff --git a/include/fs.hpp b/include/fs.hpp index 0a372bc..e570e57 100644 --- a/include/fs.hpp +++ b/include/fs.hpp @@ -12,8 +12,8 @@ public: Fs(RawDisk *disk); ~Fs(); - int allocate_datablock(INode_Data *inode_data); - int deallocate_datablock(INode_Data *inode_data); + int allocate_datablock(INode_Data *inode_data, u_int64_t *datablock_num); + int deallocate_datablock(INode_Data *inode_data, u_int64_t *datablock_num); int format(); @@ -29,8 +29,8 @@ 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); - int deallocate_indirect(u_int64_t *storage, int n); + 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); }; #endif \ No newline at end of file diff --git a/lib/fs/datablock_manager.cpp b/lib/fs/datablock_manager.cpp index c5f5054..e6737d7 100644 --- a/lib/fs/datablock_manager.cpp +++ b/lib/fs/datablock_manager.cpp @@ -1,136 +1,136 @@ -#include "fs.hpp" - -DataBlock_Manager::DataBlock_Manager(Fs *fs, u_int64_t block_segment_start, - u_int64_t block_segment_end) - : fs(fs), block_segment_start(block_segment_start), - block_segment_end(block_segment_end) {} - -class BitmapBlock_Data { -public: - char buf[IO_BLOCK_SIZE]; - u_int64_t datablocks_per_bitmap; - - BitmapBlock_Data(u_int64_t datablocks_per_bitmap_) - : datablocks_per_bitmap(datablocks_per_bitmap_) {} - - u_int64_t get_next_node() { - u_int64_t block_num; - read_u64(&block_num, buf); - return block_num; - } - void set_next_node(u_int64_t block_num) { write_u64(block_num, buf); } - - u_int64_t find_unfilled() { - const char *data = &buf[8]; - u_int64_t i = 0; - - for (; i < datablocks_per_bitmap; ++i) - if ((data[i / 8] & (1 << (i % 8))) == 0) - return i + 1; - - return 0; - } - u_int64_t claim_relative_block() { - u_int64_t unfilled = find_unfilled(); - if (unfilled) - buf[((unfilled - 1) / 8) + 8] |= (1 << ((unfilled - 1) % 8)); - return unfilled; - } - - void release_relative_block(u_int64_t relative_block_num) { - relative_block_num -= 1; - size_t index = (relative_block_num / 8) + 8; - int offset = relative_block_num % 8; - buf[index] &= ~(1 << offset); - } -}; - -int DataBlock_Manager_Bitmap::new_datablock(u_int64_t *block_num) { - int err; - BitmapBlock_Data bitmap = BitmapBlock_Data(DATABLOCKS_PER_BITMAP_BLOCK); - u_int64_t bitmap_block_num = fs->superblock.free_list_head; - char zero_buf[IO_BLOCK_SIZE] = {0}; - - if (bitmap_block_num < block_segment_start || - bitmap_block_num >= block_segment_end) - return -1; - - if ((err = fs->disk->read_block(bitmap_block_num, bitmap.buf)) < 0) - return err; - - u_int64_t relative_block_num = bitmap.claim_relative_block(); - - if (relative_block_num == 0) - return -1; - - u_int64_t block_num_ = relative_block_num + bitmap_block_num; - - // NOTE: this could be removed for speed - if ((err = fs->disk->write_block(block_num_, zero_buf)) < 0) - return err; - - // Could be optimized - if (bitmap.find_unfilled() == 0) { - if ((err = fs->save_free_list_head(bitmap.get_next_node())) < 0) - return err; - bitmap.set_next_node(0); - } - - if ((err = fs->disk->write_block(bitmap_block_num, bitmap.buf)) < 0) - return err; - - (*block_num) = block_num_; - return 0; -} - -int DataBlock_Manager_Bitmap::free_datablock(u_int64_t block_num) { - int err; - BitmapBlock_Data bitmap = BitmapBlock_Data(DATABLOCKS_PER_BITMAP_BLOCK); - const u_int64_t bitmap_region_size = DATABLOCKS_PER_BITMAP_BLOCK + 1; - bool update_freelist = false; - - u_int64_t bitmap_block_num = - (((block_num - block_segment_start) / bitmap_region_size) * - bitmap_region_size) + - block_segment_start; - - if ((err = fs->disk->read_block(bitmap_block_num, bitmap.buf)) < 0) - return err; - - if (bitmap.find_unfilled() == 0) { - update_freelist = true; - bitmap.set_next_node(fs->superblock.free_list_head); - } - - bitmap.release_relative_block(block_num - bitmap_block_num); - - if ((err = fs->disk->write_block(bitmap_block_num, bitmap.buf)) < 0) - return err; - - if (update_freelist) - if ((err = fs->save_free_list_head(bitmap_block_num)) < 0) - return err; - - return 0; - - // placing almost full bitmaps back at start of freelist is slow - // potentially like 256 times slower throughput -} - -int DataBlock_Manager_Bitmap::format() { - const u_int64_t bitmap_region_size = DATABLOCKS_PER_BITMAP_BLOCK + 1; - char buf[IO_BLOCK_SIZE] = {0}; - int err; - u_int64_t i = block_segment_start; - for (; i <= block_segment_end - (2 * bitmap_region_size); - i += bitmap_region_size) { - write_u64(i + bitmap_region_size, buf); - if ((err = fs->disk->write_block(i, buf)) < 0) - return err; - } - if ((err = fs->disk->write_block(i, buf)) < 0) - return err; - if ((err = fs->save_free_list_head(block_segment_start)) < 0) - return err; - return 0; +#include "fs.hpp" + +DataBlock_Manager::DataBlock_Manager(Fs *fs, u_int64_t block_segment_start, + u_int64_t block_segment_end) + : fs(fs), block_segment_start(block_segment_start), + block_segment_end(block_segment_end) {} + +class BitmapBlock_Data { +public: + char buf[IO_BLOCK_SIZE]; + u_int64_t datablocks_per_bitmap; + + BitmapBlock_Data(u_int64_t datablocks_per_bitmap_) + : datablocks_per_bitmap(datablocks_per_bitmap_) {} + + u_int64_t get_next_node() { + u_int64_t block_num; + read_u64(&block_num, buf); + return block_num; + } + void set_next_node(u_int64_t block_num) { write_u64(block_num, buf); } + + u_int64_t find_unfilled() { + const char *data = &buf[8]; + u_int64_t i = 0; + + for (; i < datablocks_per_bitmap; ++i) + if ((data[i / 8] & (1 << (i % 8))) == 0) + return i + 1; + + return 0; + } + u_int64_t claim_relative_block() { + u_int64_t unfilled = find_unfilled(); + if (unfilled) + buf[((unfilled - 1) / 8) + 8] |= (1 << ((unfilled - 1) % 8)); + return unfilled; + } + + void release_relative_block(u_int64_t relative_block_num) { + relative_block_num -= 1; + size_t index = (relative_block_num / 8) + 8; + int offset = relative_block_num % 8; + buf[index] &= ~(1 << offset); + } +}; + +int DataBlock_Manager_Bitmap::new_datablock(u_int64_t *block_num) { + int err; + BitmapBlock_Data bitmap = BitmapBlock_Data(DATABLOCKS_PER_BITMAP_BLOCK); + u_int64_t bitmap_block_num = fs->superblock.free_list_head; + char zero_buf[IO_BLOCK_SIZE] = {0}; + + if (bitmap_block_num < block_segment_start || + bitmap_block_num >= block_segment_end) + return -1; + + if ((err = fs->disk->read_block(bitmap_block_num, bitmap.buf)) < 0) + return err; + + u_int64_t relative_block_num = bitmap.claim_relative_block(); + + if (relative_block_num == 0) + return -1; + + u_int64_t block_num_ = relative_block_num + bitmap_block_num; + + // NOTE: this could be removed for speed + if ((err = fs->disk->write_block(block_num_, zero_buf)) < 0) + return err; + + // Could be optimized + if (bitmap.find_unfilled() == 0) { + if ((err = fs->save_free_list_head(bitmap.get_next_node())) < 0) + return err; + bitmap.set_next_node(0); + } + + if ((err = fs->disk->write_block(bitmap_block_num, bitmap.buf)) < 0) + return err; + + (*block_num) = block_num_; + return 0; +} + +int DataBlock_Manager_Bitmap::free_datablock(u_int64_t block_num) { + int err; + BitmapBlock_Data bitmap = BitmapBlock_Data(DATABLOCKS_PER_BITMAP_BLOCK); + const u_int64_t bitmap_region_size = DATABLOCKS_PER_BITMAP_BLOCK + 1; + bool update_freelist = false; + + u_int64_t bitmap_block_num = + (((block_num - block_segment_start) / bitmap_region_size) * + bitmap_region_size) + + block_segment_start; + + if ((err = fs->disk->read_block(bitmap_block_num, bitmap.buf)) < 0) + return err; + + if (bitmap.find_unfilled() == 0) { + update_freelist = true; + bitmap.set_next_node(fs->superblock.free_list_head); + } + + bitmap.release_relative_block(block_num - bitmap_block_num); + + if ((err = fs->disk->write_block(bitmap_block_num, bitmap.buf)) < 0) + return err; + + if (update_freelist) + if ((err = fs->save_free_list_head(bitmap_block_num)) < 0) + return err; + + return 0; + + // placing almost full bitmaps back at start of freelist is slow + // potentially like 256 times slower throughput +} + +int DataBlock_Manager_Bitmap::format() { + const u_int64_t bitmap_region_size = DATABLOCKS_PER_BITMAP_BLOCK + 1; + char buf[IO_BLOCK_SIZE] = {0}; + int err; + u_int64_t i = block_segment_start; + for (; i <= block_segment_end - (2 * bitmap_region_size); + i += bitmap_region_size) { + write_u64(i + bitmap_region_size, buf); + if ((err = fs->disk->write_block(i, buf)) < 0) + return err; + } + if ((err = fs->disk->write_block(i, buf)) < 0) + return err; + if ((err = fs->save_free_list_head(block_segment_start)) < 0) + return err; + return 0; } \ No newline at end of file diff --git a/lib/fs/fs_resize.cpp b/lib/fs/fs_resize.cpp index c700828..194c064 100644 --- a/lib/fs/fs_resize.cpp +++ b/lib/fs/fs_resize.cpp @@ -1,25 +1,27 @@ #include "fs.hpp" -int Fs::allocate_datablock(INode_Data *inode_data) { +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) - if (inode_data->direct_blocks[i] == 0) { - if ((result = datablock_manager->new_datablock( - &(inode_data->direct_blocks[i]))) < 0) - return result; - return 0; - } + 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); + 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); + 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); + result = + allocate_indirect(&(inode_data->triple_indirect_block), 3, datablock_num); if (result <= 0) return result; @@ -28,15 +30,17 @@ int Fs::allocate_datablock(INode_Data *inode_data) { // 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) { +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) + if (n == 0) { + (*datablock_num) = (*storage); return 0; + } } if (n == 0) @@ -49,7 +53,7 @@ int Fs::allocate_indirect(u_int64_t *storage, int n) { 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); + result = allocate_indirect(&temp, n - 1, datablock_num); if (result < 0) return result; if (result == 0) { @@ -63,34 +67,36 @@ int Fs::allocate_indirect(u_int64_t *storage, int n) { return 1; } -int Fs::deallocate_datablock(INode_Data *inode_data) { +int Fs::deallocate_datablock(INode_Data *inode_data, u_int64_t *datablock_num) { int result; - result = deallocate_indirect(&(inode_data->triple_indirect_block), 3); + 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); + 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); + 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) - if (inode_data->direct_blocks[i] != 0) { - if ((result = datablock_manager->free_datablock( - inode_data->direct_blocks[i])) < 0) - return result; - inode_data->direct_blocks[i] = 0; - return 0; - } + 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) { +int Fs::deallocate_indirect(u_int64_t *storage, int n, + u_int64_t *datablock_num) { char buf[IO_BLOCK_SIZE]; int result; @@ -98,8 +104,10 @@ int Fs::deallocate_indirect(u_int64_t *storage, int n) { 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; } @@ -112,7 +120,7 @@ int Fs::deallocate_indirect(u_int64_t *storage, int n) { 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); + result = deallocate_indirect(&temp, n - 1, datablock_num); if (result < 0) return result; if (result == 0) { diff --git a/lib/fs/inode_manager.cpp b/lib/fs/inode_manager.cpp index c9d2599..33166ad 100644 --- a/lib/fs/inode_manager.cpp +++ b/lib/fs/inode_manager.cpp @@ -1,132 +1,134 @@ -#include "fs.hpp" - -INode_Manager::INode_Manager(Fs *fs, u_int64_t block_segment_start, - u_int64_t block_segment_end) - : fs(fs), block_segment_start(block_segment_start), - block_segment_end(block_segment_end) { - max_num_inodes = (block_segment_end - block_segment_start) * INODES_PER_BLOCK; -} - -u_int64_t INode_Manager::get_block_num(u_int64_t inode_num) { - u_int64_t block_num = block_segment_start + (inode_num / INODES_PER_BLOCK); - if (block_num >= block_segment_end) - return 0; - return block_num; -} -u_int64_t INode_Manager::get_block_offset(u_int64_t inode_num) { - return (inode_num % INODES_PER_BLOCK) * INODE_SIZE; -} - -int INode_Manager::load_inode(INode_Data *inode_data) { - char buf[IO_BLOCK_SIZE]; - int err; - - u_int64_t block_num = get_block_num(inode_data->inode_num); - if (block_num == 0) - return -1; - u_int64_t block_offset = get_block_offset(inode_data->inode_num); - - if ((err = fs->disk->read_block(block_num, buf)) < 0) - return err; - - inode_data->deserialize(&buf[block_offset]); - - return 0; -} -int INode_Manager::save_inode(INode_Data *inode_data) { - char buf[IO_BLOCK_SIZE]; - int err; - - u_int64_t block_num = get_block_num(inode_data->inode_num); - if (block_num == 0) - return -1; - u_int64_t block_offset = get_block_offset(inode_data->inode_num); - - if ((err = fs->disk->read_block(block_num, buf)) < 0) - return err; - - inode_data->serialize(&buf[block_offset]); - - if ((err = fs->disk->write_block(block_num, buf)) < 0) - return err; - - return 0; -} - -int INode_Manager_Freelist::new_inode(u_int64_t uid, u_int64_t gid, - u_int64_t permissions, - INode_Data *inode_data) { - char buf[IO_BLOCK_SIZE]; - int err; - u_int64_t inode_num = fs->superblock.inode_list_head; - if (inode_num > max_num_inodes) - return -1; - - u_int64_t block_num = get_block_num(inode_num); - u_int64_t block_offset = get_block_offset(inode_num); - - if (block_num == 0) - return -1; - - if ((err = fs->disk->read_block(block_num, buf)) < 0) - return err; - - u_int64_t new_inode_list_head = 0; - read_u64(&new_inode_list_head, &buf[block_offset]); - if ((err = fs->save_inode_list_head(new_inode_list_head)) < 0) - return err; - - (*inode_data) = INode_Data(inode_num); - - inode_data->metadata.uid = uid; - inode_data->metadata.gid = gid; - inode_data->metadata.permissions = permissions; - - // It is debatable if this function should do this: - if ((err = save_inode(inode_data)) < 0) { - inode_data->inode_num = 0xFFFFFFFFFFFFFFFF; - return err; - } - - return 0; -} -int INode_Manager_Freelist::free_inode(INode_Data *inode_data) { - char buf[IO_BLOCK_SIZE]; - int err; - - u_int64_t block_num = get_block_num(inode_data->inode_num); - u_int64_t block_offset = get_block_offset(inode_data->inode_num); - - if (block_num == 0) - return -1; - - if ((err = fs->disk->read_block(block_num, buf)) < 0) - return err; - - write_u64(fs->superblock.inode_list_head, &buf[block_offset]); - - if ((err = fs->disk->write_block(block_num, buf)) < 0) - return err; - - if ((err = fs->save_inode_list_head(inode_data->inode_num)) < 0) - return err; - - return 0; -} - -int INode_Manager_Freelist::format() { - char buf[IO_BLOCK_SIZE]; - int err; - u_int64_t next_inode_num = 1; - for (u_int64_t i = block_segment_start; i < block_segment_end; ++i) { - for (int j = 0; j < INODES_PER_BLOCK; ++next_inode_num, ++j) - write_u64(next_inode_num, &buf[j * INODE_SIZE]); - if ((err = fs->disk->write_block(i, buf)) < 0) - return err; - } - if ((err = fs->save_inode_list_head(0)) < 0) - return err; - return 0; -} - - +#include "fs.hpp" + +INode_Manager::INode_Manager(Fs *fs, u_int64_t block_segment_start, + u_int64_t block_segment_end) + : fs(fs), block_segment_start(block_segment_start), + block_segment_end(block_segment_end) { + max_num_inodes = (block_segment_end - block_segment_start) * INODES_PER_BLOCK; +} + +u_int64_t INode_Manager::get_block_num(u_int64_t inode_num) { + if (inode_num > max_num_inodes || inode_num == 0) + return 0; + u_int64_t block_num = + block_segment_start + ((inode_num - 1) / INODES_PER_BLOCK); + return block_num; +} +u_int64_t INode_Manager::get_block_offset(u_int64_t inode_num) { + return ((inode_num - 1) % INODES_PER_BLOCK) * INODE_SIZE; +} + +int INode_Manager::load_inode(INode_Data *inode_data) { + char buf[IO_BLOCK_SIZE]; + int err; + + u_int64_t block_num = get_block_num(inode_data->inode_num); + if (block_num == 0) + return -1; + u_int64_t block_offset = get_block_offset(inode_data->inode_num); + + if ((err = fs->disk->read_block(block_num, buf)) < 0) + return err; + + inode_data->deserialize(&buf[block_offset]); + + return 0; +} +int INode_Manager::save_inode(INode_Data *inode_data) { + char buf[IO_BLOCK_SIZE]; + int err; + + u_int64_t block_num = get_block_num(inode_data->inode_num); + if (block_num == 0) + return -1; + u_int64_t block_offset = get_block_offset(inode_data->inode_num); + + if ((err = fs->disk->read_block(block_num, buf)) < 0) + return err; + + inode_data->serialize(&buf[block_offset]); + + if ((err = fs->disk->write_block(block_num, buf)) < 0) + return err; + + return 0; +} + +int INode_Manager_Freelist::new_inode(u_int64_t uid, u_int64_t gid, + u_int64_t permissions, + INode_Data *inode_data) { + char buf[IO_BLOCK_SIZE]; + int err; + u_int64_t inode_num = fs->superblock.inode_list_head; + if (inode_num > max_num_inodes) + return -1; + + u_int64_t block_num = get_block_num(inode_num); + u_int64_t block_offset = get_block_offset(inode_num); + + if (block_num == 0) + return -1; + + if ((err = fs->disk->read_block(block_num, buf)) < 0) + return err; + + u_int64_t new_inode_list_head = 0; + read_u64(&new_inode_list_head, &buf[block_offset]); + if ((err = fs->save_inode_list_head(new_inode_list_head)) < 0) + return err; + + (*inode_data) = INode_Data(inode_num); + + inode_data->metadata.uid = uid; + inode_data->metadata.gid = gid; + inode_data->metadata.permissions = permissions; + + // It is debatable if this function should do this: + if ((err = save_inode(inode_data)) < 0) { + inode_data->inode_num = 0xFFFFFFFFFFFFFFFF; + return err; + } + + return 0; +} +int INode_Manager_Freelist::free_inode(INode_Data *inode_data) { + char buf[IO_BLOCK_SIZE]; + int err; + + u_int64_t block_num = get_block_num(inode_data->inode_num); + u_int64_t block_offset = get_block_offset(inode_data->inode_num); + + if (block_num == 0) + return -1; + + if ((err = fs->disk->read_block(block_num, buf)) < 0) + return err; + + write_u64(fs->superblock.inode_list_head, &buf[block_offset]); + + if ((err = fs->disk->write_block(block_num, buf)) < 0) + return err; + + if ((err = fs->save_inode_list_head(inode_data->inode_num)) < 0) + return err; + + return 0; +} + +int INode_Manager_Freelist::format() { + char buf[IO_BLOCK_SIZE]; + int err; + u_int64_t next_inode_num = 2; + for (u_int64_t i = block_segment_start; i < block_segment_end; ++i) { + for (int j = 0; j < INODES_PER_BLOCK; ++next_inode_num, ++j) { + if (next_inode_num > max_num_inodes) + next_inode_num = 0; + write_u64(next_inode_num, &buf[j * INODE_SIZE]); + } + if ((err = fs->disk->write_block(i, buf)) < 0) + return err; + } + if ((err = fs->save_inode_list_head(1)) < 0) + return err; + return 0; +} diff --git a/lib/main.cpp b/lib/main.cpp index 8aed40b..13291c9 100644 --- a/lib/main.cpp +++ b/lib/main.cpp @@ -15,11 +15,12 @@ int main() { INode_Data inode_data = INode_Data(); fs->inode_manager->new_inode(1, 2, 3, &inode_data); int err; + u_int64_t block_num = 0; for (int i = 0; i < 56 + 512 + 4; ++i) - err = fs->allocate_datablock(&inode_data); + err = fs->allocate_datablock(&inode_data, &block_num); for (int i = 0; i < 5; ++i) - printf("%d\n", err = fs->deallocate_datablock(&inode_data)); + printf("%d\n", err = fs->deallocate_datablock(&inode_data, &block_num)); fs->inode_manager->save_inode(&inode_data); diff --git a/lib/rawdisk.cpp b/lib/rawdisk.cpp index c033bc2..c0ed0ab 100644 --- a/lib/rawdisk.cpp +++ b/lib/rawdisk.cpp @@ -12,7 +12,9 @@ void RawDisk::print_block(u_int64_t block_number) { printf("\nBlock %llu:\n", block_number); for (int i = 0; i < IO_BLOCK_SIZE; i += sizeof(u_int64_t)) { - read_u64(&num, &buf[i]); + num = 0; + for (int j = 0; j < 8; j++) + num |= ((u_int64_t)(unsigned char)buf[i + j]) << (8 * j); printf("%llu ", num); if ((i / sizeof(u_int64_t)) % nums_per_line == nums_per_line - 1) printf("\n"); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 41d7049..e92ee57 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,23 +1,34 @@ set(TARGET_LAYER0 test_layer0) set(TARGET_LAYER1_API test_layer1_API) -set(TARGET_LAYER1_TEST1 test_layer1_test1) +# set(TARGET_LAYER1_TEST1 test_layer1_test1) set(DIR_PLACE /dev/vdb) # add test sources here ... add_executable(${TARGET_LAYER0} # add need lib and source code here layer0.cpp + + ../lib/rawdisk.cpp + ) add_executable(${TARGET_LAYER1_API} # add need lib and source code here layer1_API.cpp + + ../lib/fischl.cpp + ../lib/rawdisk.cpp + ../lib/fs/datablock_manager.cpp + ../lib/fs/fs_data_types.cpp + ../lib/fs/fs_resize.cpp + ../lib/fs/fs.cpp + ../lib/fs/inode_manager.cpp ) -add_executable(${TARGET_LAYER1_TEST1} - # add need lib and source code here - layer1_test1.cpp -) +# add_executable(${TARGET_LAYER1_TEST1} +# # add need lib and source code here +# layer1_test1.cpp +# ) # add test to activate ctest -VV add_test(NAME ${TARGET_LAYER0} COMMAND sudo ./${TARGET_LAYER0} ${DIR_PLACE}) add_test(NAME ${TARGET_LAYER1_API} COMMAND sudo ./${TARGET_LAYER1_API} ${DIR_PLACE}) -add_test(NAME ${TARGET_LAYER1_TEST1} COMMAND sudo ./${TARGET_LAYER1_TEST1} ${DIR_PLACE}) \ No newline at end of file +# add_test(NAME ${TARGET_LAYER1_TEST1} COMMAND sudo ./${TARGET_LAYER1_TEST1} ${DIR_PLACE}) \ No newline at end of file diff --git a/test/layer0.cpp b/test/layer0.cpp index 122f066..265ad60 100644 --- a/test/layer0.cpp +++ b/test/layer0.cpp @@ -1,29 +1,32 @@ +#include "rawdisk.hpp" +#include #include #include -#include -#include "rawdisk.h" int main(int argc, char *argv[]) { - const char* d = (argc < 2) ? "/dev/vdc" : argv[1]; - - RawDisk *H = new RawDisk(d); - - char *buf = "iloveosdfjlseirfnerig"; - char readBuffer[512] = {0}; // Initialize to zeros + const char *d = (argc < 2) ? "/dev/vdc" : argv[1]; - //printf("dir %s, numSectors %lld, diskSize %lld \n", H->dir, H->numSectors, H->diskSize); + RawDisk *H = new RealRawDisk(d); - //use number to substitute H->getnumSector(), getnumSectors() are not yest implemented - for(u_int64_t i = 0; i < 10; i++) { - H->rawdisk_write(i*512, buf, strlen(buf));//Change write_API - } - //use number to substitute H->getnumSector(), getnumSectors() are not yest implemented - for(u_int64_t i = 0; i < 10; i++) { - H->rawdisk_read(i*512, readBuffer, sizeof(readBuffer));//Change read_API - assert(strncmp(readBuffer, buf, strlen(buf)) == 0); - } + char *buf = "iloveosdfjlseirfnerig"; + char readBuffer[IO_BLOCK_SIZE] = {0}; // Initialize to zeros - delete H; // Delete the RawDisk object + // printf("dir %s, numSectors %lld, diskSize %lld \n", H->dir, H->numSectors, + // H->diskSize); - return 0; + // use number to substitute H->getnumSector(), getnumSectors() are not yest + // implemented + for (u_int64_t i = 0; i < 10; i++) { + H->write_block(i, buf); // Change write_API + } + // use number to substitute H->getnumSector(), getnumSectors() are not yest + // implemented + for (u_int64_t i = 0; i < 10; i++) { + H->read_block(i, readBuffer); // Change read_API + assert(strncmp(readBuffer, buf, strlen(buf)) == 0); + } + + delete H; // Delete the RawDisk object + + return 0; } diff --git a/test/layer1_API.cpp b/test/layer1_API.cpp index e898231..b49f0b2 100644 --- a/test/layer1_API.cpp +++ b/test/layer1_API.cpp @@ -1,118 +1,144 @@ +#include "fs.hpp" +#include +#include #include #include -#include -#include "fs.h" -#include int main(int argc, char *argv[]) { - const char* d = (argc < 2) ? "/dev/vdc" : argv[1]; - - RawDisk *H = new RawDisk(d); + // const char* d = (argc < 2) ? "/dev/vdc" : argv[1]; - printf("test inode\n"); - INodeOperation inop; - inop.initialize(*H);//for inode initialization and datablock initialization - char buffer[8] = {0}; - /**************************test inode Initialization***************************/ - //test the begining of inode 1th - H->rawdisk_read((1) * SECTOR_SIZE, buffer, sizeof(buffer)); - u_int64_t t = 0; - for (int j = 0; j < 8; j++) - t |= ((u_int64_t)(unsigned char)buffer[j]) << (8 * j); + RawDisk *H = new FakeRawDisk(2048); + Fs *fs = new Fs(H); - assert(t == 2);//the first 1th unused inode will store the next unused inode 2th - //test the number before end of inode 524286th - H->rawdisk_read((MAX_INODE - 2) * SECTOR_SIZE, buffer, sizeof(buffer)); - t = 0; - for (int j = 0; j < 8; j++) - t |= ((u_int64_t)(unsigned char)buffer[j]) << (8 * j); - - assert(t == MAX_INODE - 1);//store the maximun th inode - //test the end of inode 524287th - H->rawdisk_read((MAX_INODE - 1) * SECTOR_SIZE, buffer, sizeof(buffer)); - t = 0; - for (int j = 0; j < 8; j++) - t |= ((u_int64_t)(unsigned char)buffer[j]) << (8 * j); + printf("test inode\n"); + fs->format(); + char buffer[IO_BLOCK_SIZE] = {0}; + /**************************test inode + * Initialization***************************/ + // test the begining of inode 1th + H->read_block(1, buffer); + u_int64_t t = 0; + for (int j = 0; j < 8; j++) + t |= ((u_int64_t)(unsigned char)buffer[j]) << (8 * j); - assert(t == 0);//the end of inode(524287th inode) do not have the next inode address - /**************************test datablock Initialization***************************/ - //we separate 2048 4kB I/O block(1+2047) as a group and the first I/O block will manage the following 2047 I/O block usage. - //the first 8 bytes(0~7) in first I/O block store the address of next first I/O block, the following 256(8~263) bytes record 2047 I/O block usage. - //test the begining of free datablock - H->rawdisk_read((MAX_INODE) * SECTOR_SIZE, buffer, sizeof(buffer));//the begining of free datablock will store from address (MAX_INODE) * SECTOR_SIZE - t = 0; - for (int j = 0; j < 8; j++) - t |= ((u_int64_t)(unsigned char)buffer[j]) << (8 * j); + assert(t == + 2); // the first 1th unused inode will store the next unused inode 2th - assert(t == (MAX_INODE+2048*8)*SECTOR_SIZE);//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->rawdisk_read((MAX_BLOCKNUM - 2048*8) * SECTOR_SIZE, buffer, sizeof(buffer)); - t = 0; - for (int j = 0; j < 8; j++) - t |= ((u_int64_t)(unsigned char)buffer[j]) << (8 * j); + assert(IO_BLOCK_SIZE == 4096); + assert(INODE_SIZE == 512); - assert(t == (MAX_BLOCKNUM)*SECTOR_SIZE); + // test the number before end of inode + H->read_block(NUM_INODE_BLOCKS, buffer); + t = 0; + for (int j = 0; j < 8; j++) + t |= + ((u_int64_t)(unsigned char)buffer[j + IO_BLOCK_SIZE - (INODE_SIZE * 2)]) + << (8 * j); - /***************************test inode de/allocation**********************************/ - //when requesting an inode, the inode_allocation will give you the inode number, we use inode_list to store the sequence allocate inode - //arrary version - int inode_list[20] = {0}; - int record_free[10] = {0};//should do a pop up structure to record the free inode - int rec = 9; - //printf("Allocate 20 inode num:{"); - for(int i=0;i<20;i++){ - inode_list[i] = inop.inode_allocate(*H); - assert(inode_list[i] == i+1); - //printf(" %d", inode_list[i]); + assert(t == NUM_INODE_BLOCKS * + (IO_BLOCK_SIZE / INODE_SIZE)); // store the maximun th inode + + // test the end of inode + t = 0; + for (int j = 0; j < 8; j++) + t |= ((u_int64_t)(unsigned char)buffer[j + IO_BLOCK_SIZE - INODE_SIZE]) + << (8 * j); + + assert( + t == + 0); // the end of inode(524287th inode) do not have the next inode address + /**************************test datablock + * Initialization***************************/ + // we separate 2048 4kB I/O block(1+2047) as a group and the first I/O block + // will manage the following 2047 I/O block usage. the first 8 bytes(0~7) in + // first I/O block store the address of next first I/O block, the following + // 256(8~263) bytes record 2047 I/O block usage. test the begining of free + // datablock + H->read_block(NUM_INODE_BLOCKS + 1, + buffer); // the begining of free datablock will store + // from address (MAX_INODE) * SECTOR_SIZE + t = 0; + for (int j = 0; j < 8; j++) + t |= ((u_int64_t)(unsigned char)buffer[j]) << (8 * j); + + assert(t == NUM_INODE_BLOCKS + 1 + DATABLOCKS_PER_BITMAP_BLOCK + + 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); + + assert(t == NUM_BLOCKS - DATABLOCKS_PER_BITMAP_BLOCK - 1); + + /***************************test inode + * de/allocation**********************************/ + // when requesting an inode, the inode_allocation will give you the inode + // number, we use inode_list to store the sequence allocate inode arrary + // version + INode_Data inode_list[20]; + u_int64_t record_free[10] = { + 0}; // should do a pop up structure to record the free inode + int rec = 9; + // printf("Allocate 20 inode num:{"); + for (int i = 0; i < 20; i++) { + fs->inode_manager->new_inode(0, 0, 0, &inode_list[i]); + + assert(inode_list[i].inode_num == i + 1); + // printf(" %d", inode_list[i].inode_num); + } + // printf("}\n"); + for (int i = 10; i < 20; i++) { + record_free[i - 10] = inode_list[i].inode_num; + fs->inode_manager->free_inode( + &inode_list[i]); // free the 10 element from inode_list[10] + } + // allocate again the last 10 + printf("Allocate again: inode num:{"); + for (int i = 10; i < 20; i++) { + fs->inode_manager->new_inode(0, 0, 0, &inode_list[i]); + // printf("inode %d, rec_f %d\n,", inode_list[i],record_free[rec]); + assert(inode_list[i].inode_num == record_free[rec]); + rec--; + } + printf("}\n"); + /***************************test direct blocks[48] + * de/allocation**********************************/ + // 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=10;i<20;i++){ - inop.inode_free(*H,inode_list[i]);//free the 10 element from inode_list[10] - record_free[i-10] = inode_list[i]; - } - //allocate again the last 10 - printf("Allocate again: inode num:{"); - for(int i=10;i<20;i++){ - inode_list[i] = inop.inode_allocate(*H); - //printf("inode %d, rec_f %d\n,", inode_list[i],record_free[rec]); - assert(inode_list[i] == record_free[rec]); - rec--; - } - printf("}\n"); - /***************************test direct blocks[48] de/allocation**********************************/ - //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 - INode inode_inside[10]; - u_int64_t rec_datablock_free[10][3] = {0};//array version - for(int i=0;i<10;i++){ - inode_inside[i].inode_construct(inode_list[i],*H); - //printf("%dth data block starting addres: ", i); - for(int j=0;j<6;j++){ - inode_inside[i].datablock_allocate(*H); - //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--){ - rec_datablock_free[i][j] = inode_inside[i].datablock_deallocate(*H); - //printf("", rec_datablock_free[i][j]); - } - //printf("\n"); + // 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++){ - assert(inode_inside[i].datablock_allocate(*H) == 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 + // printf("}\n"); + delete H; // Delete the RawDisk object - return 0; + return 0; } diff --git a/test/layer1_test1.cpp b/test/layer1_test1.cpp index 2943ecd..ee760a4 100644 --- a/test/layer1_test1.cpp +++ b/test/layer1_test1.cpp @@ -1,113 +1,130 @@ -#include -#include -#include -#include "fs.h" -#include - -// in fs.h: -// #define MAX_INODE 2048 -// #define MAX_BLOCKNUM 51200 -// 51200 Sectors = 2048 * 25 Sectors = 25MB -// Free List Heads: 2048*512, 2048*9*512, 2048*17*512 -// Available INodes: 2047 (-1 because superblock) -// Available DataBlocks (including Indirect Blocks): 2047 * 3 = 6141 - -int main(int argc, char *argv[]) { - const char* d = (argc < 2) ? "/dev/vdc" : argv[1]; - - RawDisk *H = new RawDisk(d); - - printf("=== INode Alloc/Dealloc Test ===\n"); - INodeOperation inop; - inop.initialize(*H); - - // Test INode alloc and dealloc - int inode_list[2046] = {0}; // if we allocate 2047 inodes head will be 0 (faulty) - printf("freeInodeHead: %d \n", SuperBlock::getFreeINodeHead(*H)); // this impl should give 1 - for(int i=0;i<2046;i++){ - inode_list[i] = inop.inode_allocate(*H); - if (SuperBlock::getFreeINodeHead(*H) == 0) { - printf("%d\n",i); - assert(false); - } - } - printf("freeInodeHead: %d \n", SuperBlock::getFreeINodeHead(*H)); // this impl should give 2047 - for(int i=0;i<1024;i++){ - inop.inode_free(*H,inode_list[i]); - } - for(int i=0;i<1022;i++){ - inode_list[i] = inop.inode_allocate(*H); - assert(SuperBlock::getFreeINodeHead(*H) != 0); - } - printf("freeInodeHead: %d \n", SuperBlock::getFreeINodeHead(*H)); // this impl should give 2 - inode_list[1022] = inop.inode_allocate(*H); - printf("freeInodeHead: %d \n", SuperBlock::getFreeINodeHead(*H)); // this impl should give 1 - inode_list[1023] = inop.inode_allocate(*H); - printf("freeInodeHead: %d \n", SuperBlock::getFreeINodeHead(*H)); // this impl should give 2047 - - // Test Many Files - printf("=== Many Files Test ===\n"); - INode inode_inside[100]; - for(int i=0;i<100;i++){ - inode_inside[i].inode_construct(inode_list[i],*H); - for(int j=0;j<60;j++) { // Note that 1 indirect block is used for each file - u_int64_t allcBlockNum = inode_inside[i].datablock_allocate(*H); - if (SuperBlock::getFreeListHead(*H) >= (u_int64_t) 51200*512) { - printf("Bad FreeListHead: %d, %d, %llu\n", i, j, SuperBlock::getFreeListHead(*H)); - assert(false); - } - if (allcBlockNum % 2048 != 0 || allcBlockNum < 2048*512 || allcBlockNum >= 25*2048*512) { - printf("Bad Allocated Block Number: %d, %d, %llu\n", i, j, allcBlockNum); - assert(false); - } - } - } - printf("Finished Allocating\n"); - // in this impl should give 17*2048*512 = 17825792 - printf("freeListHead: %llu \n", SuperBlock::getFreeListHead(*H)); // if all 6141 blocks allocated, would give 51200*512 (faulty) - for(int i=0;i<100;i++){ - for(int j=0;j<59;j++){ - u_int64_t freedBlkNum = inode_inside[i].datablock_deallocate(*H); - u_int64_t fh = SuperBlock::getFreeListHead(*H); - if (freedBlkNum % 2048 != 0 || freedBlkNum < 2048*512 || freedBlkNum >= 25*2048*512 || fh >= 51200*512) { - printf("%d, %d, Freed Block Number: %llu\n", i, j, freedBlkNum); - printf("FreeListHead is %llu\n", fh); - assert(false); - } - } - } - printf("Finished Deallocating\n"); - printf("freeListHead: %d \n", SuperBlock::getFreeListHead(*H)); - - // Test Big File (Use direct, single indirect, double indirect) - printf("=== Big File Test ===\n"); - u_int64_t lastAllc = 0; - for(int j=0;j<5000;j++){ - u_int64_t allcBlockNum = inode_inside[0].datablock_allocate(*H); - lastAllc = allcBlockNum; - u_int64_t fh = SuperBlock::getFreeListHead(*H); - if (allcBlockNum % 2048 != 0 || allcBlockNum < 2048*512 || allcBlockNum >= 25*2048*512 || fh >= 51200*512) { - printf("%d, Alloc Block Number: %llu\n", j, allcBlockNum); - printf("FreeListHead is %llu\n", fh); - assert(false); - } - } - printf("last allocate for big file: %llu\n", lastAllc); - printf("Finished Allocating\n"); - printf("freeListHead: %d \n", SuperBlock::getFreeListHead(*H)); - for(int j=0;j<5000;j++){ - u_int64_t freedBlkNum = inode_inside[0].datablock_deallocate(*H); - u_int64_t fh = SuperBlock::getFreeListHead(*H); - if (freedBlkNum % 2048 != 0 || freedBlkNum < 2048*512 || freedBlkNum >= 25*2048*512 || fh >= 51200*512) { - printf("%d, Freed Block Number: %llu\n", j, freedBlkNum); - printf("FreeListHead is %llu\n", fh); - assert(false); - } - } - printf("Finished Deallocating\n"); - printf("freeListHead: %d \n", SuperBlock::getFreeListHead(*H)); - - delete H; // Delete the RawDisk object - - return 0; -} +// #include "fs.h" +// #include +// #include +// #include +// #include + +// // in fs.h: +// // #define MAX_INODE 2048 +// // #define MAX_BLOCKNUM 51200 +// // 51200 Sectors = 2048 * 25 Sectors = 25MB +// // Free List Heads: 2048*512, 2048*9*512, 2048*17*512 +// // Available INodes: 2047 (-1 because superblock) +// // Available DataBlocks (including Indirect Blocks): 2047 * 3 = 6141 + +// int main(int argc, char *argv[]) { +// const char *d = (argc < 2) ? "/dev/vdc" : argv[1]; + +// RawDisk *H = new FakeRawDisk(d); + +// printf("=== INode Alloc/Dealloc Test ===\n"); +// INodeOperation inop; +// inop.initialize(*H); + +// // Test INode alloc and dealloc +// int inode_list[2046] = { +// 0}; // if we allocate 2047 inodes head will be 0 (faulty) +// printf("freeInodeHead: %d \n", +// SuperBlock::getFreeINodeHead(*H)); // this impl should give 1 +// for (int i = 0; i < 2046; i++) { +// inode_list[i] = inop.inode_allocate(*H); +// if (SuperBlock::getFreeINodeHead(*H) == 0) { +// printf("%d\n", i); +// assert(false); +// } +// } +// printf("freeInodeHead: %d \n", +// SuperBlock::getFreeINodeHead(*H)); // this impl should give 2047 +// for (int i = 0; i < 1024; i++) { +// inop.inode_free(*H, inode_list[i]); +// } +// for (int i = 0; i < 1022; i++) { +// inode_list[i] = inop.inode_allocate(*H); +// assert(SuperBlock::getFreeINodeHead(*H) != 0); +// } +// printf("freeInodeHead: %d \n", +// SuperBlock::getFreeINodeHead(*H)); // this impl should give 2 +// inode_list[1022] = inop.inode_allocate(*H); +// printf("freeInodeHead: %d \n", +// SuperBlock::getFreeINodeHead(*H)); // this impl should give 1 +// inode_list[1023] = inop.inode_allocate(*H); +// printf("freeInodeHead: %d \n", +// SuperBlock::getFreeINodeHead(*H)); // this impl should give 2047 + +// // Test Many Files +// printf("=== Many Files Test ===\n"); +// INode inode_inside[100]; +// for (int i = 0; i < 100; i++) { +// inode_inside[i].inode_construct(inode_list[i], *H); +// for (int j = 0; j < 60; +// j++) { // Note that 1 indirect block is used for each file +// u_int64_t allcBlockNum = inode_inside[i].datablock_allocate(*H); +// if (SuperBlock::getFreeListHead(*H) >= (u_int64_t)51200 * 512) { +// printf("Bad FreeListHead: %d, %d, %llu\n", i, j, +// SuperBlock::getFreeListHead(*H)); +// assert(false); +// } +// if (allcBlockNum % 2048 != 0 || allcBlockNum < 2048 * 512 || +// allcBlockNum >= 25 * 2048 * 512) { +// printf("Bad Allocated Block Number: %d, %d, %llu\n", i, j, +// allcBlockNum); +// assert(false); +// } +// } +// } +// printf("Finished Allocating\n"); +// // in this impl should give 17*2048*512 = 17825792 +// printf( +// "freeListHead: %llu \n", +// SuperBlock::getFreeListHead( +// *H)); // if all 6141 blocks allocated, would give 51200*512 +// (faulty) +// for (int i = 0; i < 100; i++) { +// for (int j = 0; j < 59; j++) { +// u_int64_t freedBlkNum = inode_inside[i].datablock_deallocate(*H); +// u_int64_t fh = SuperBlock::getFreeListHead(*H); +// if (freedBlkNum % 2048 != 0 || freedBlkNum < 2048 * 512 || +// freedBlkNum >= 25 * 2048 * 512 || fh >= 51200 * 512) { +// printf("%d, %d, Freed Block Number: %llu\n", i, j, freedBlkNum); +// printf("FreeListHead is %llu\n", fh); +// assert(false); +// } +// } +// } +// printf("Finished Deallocating\n"); +// printf("freeListHead: %d \n", SuperBlock::getFreeListHead(*H)); + +// // Test Big File (Use direct, single indirect, double indirect) +// printf("=== Big File Test ===\n"); +// u_int64_t lastAllc = 0; +// for (int j = 0; j < 5000; j++) { +// u_int64_t allcBlockNum = inode_inside[0].datablock_allocate(*H); +// lastAllc = allcBlockNum; +// u_int64_t fh = SuperBlock::getFreeListHead(*H); +// if (allcBlockNum % 2048 != 0 || allcBlockNum < 2048 * 512 || +// allcBlockNum >= 25 * 2048 * 512 || fh >= 51200 * 512) { +// printf("%d, Alloc Block Number: %llu\n", j, allcBlockNum); +// printf("FreeListHead is %llu\n", fh); +// assert(false); +// } +// } +// printf("last allocate for big file: %llu\n", lastAllc); +// printf("Finished Allocating\n"); +// printf("freeListHead: %d \n", SuperBlock::getFreeListHead(*H)); +// for (int j = 0; j < 5000; j++) { +// u_int64_t freedBlkNum = inode_inside[0].datablock_deallocate(*H); +// u_int64_t fh = SuperBlock::getFreeListHead(*H); +// if (freedBlkNum % 2048 != 0 || freedBlkNum < 2048 * 512 || +// freedBlkNum >= 25 * 2048 * 512 || fh >= 51200 * 512) { +// printf("%d, Freed Block Number: %llu\n", j, freedBlkNum); +// printf("FreeListHead is %llu\n", fh); +// assert(false); +// } +// } +// printf("Finished Deallocating\n"); +// printf("freeListHead: %d \n", SuperBlock::getFreeListHead(*H)); + +// delete H; // Delete the RawDisk object + +// return 0; +// }