From a15f5d9a3e63db1b5b0084aff5008349c5445b07 Mon Sep 17 00:00:00 2001 From: FactorialN <8838579+FactorialN@users.noreply.github.com> Date: Mon, 4 Dec 2023 00:20:59 -0800 Subject: [PATCH] added clarification for running with -s --- CMakeLists.txt | 2 +- README.md | 9 +- lib/direntry.cpp | 2 +- lib/files.cpp | 68 +++------- lib/fischl.cpp | 64 +++++++++ lib/fs/fs_file_io.cpp | 13 +- lib/main.cpp | 300 +++++------------------------------------- lib/rawdisk.cpp | 6 + 8 files changed, 138 insertions(+), 326 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index eb951da..0ecb1d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,7 +26,7 @@ add_executable(fischl enable_testing() add_subdirectory(test) -# add_subdirectory(googletest) +add_subdirectory(googletest) # Add the -Wall flag target_compile_options(fischl PRIVATE -Wall) diff --git a/README.md b/README.md index d3936ef..3d24def 100644 --- a/README.md +++ b/README.md @@ -22,23 +22,24 @@ make # cmake --build . is same ## mount and test normal usage: ```bash -./fischl diskpath n mountpoint +./fischl diskpath n -s mountpoint ``` diskpath must be provided following ./fischl l/n must be provided following diskpath indicating whether to load the exisiting file system or create a new one. for loading: ```bash -./fischl diskpath l mountpoint +./fischl diskpath l -s mountpoint ``` +-s is also required because our fs doesn't support multi-threading. if the diskpath need to be accessed by root: ```bash -sudo ./fischl diskpath n -o allow_other mountpoint +sudo ./fischl diskpath n -o allow_other -s mountpoint ``` for debugging: ```bash -sudo ./fischl diskpath n -o allow_other -d mountpoint +sudo ./fischl diskpath n -o allow_other -d -s mountpoint ``` ## run test diff --git a/lib/direntry.cpp b/lib/direntry.cpp index 2c6c1ba..3b765b0 100644 --- a/lib/direntry.cpp +++ b/lib/direntry.cpp @@ -258,7 +258,7 @@ FileNode *fischl_find_entry(Fs *fs, TreeNode *root, const char *path){ } if (file != NULL && file->subdirectory == NULL) { free(pathCopy); - //printf("FOUND !! %llu\n", file->inode_number); + printf("FOUND !! %llu\n", file->inode_number); return file; //File found //return current; return filenode } diff --git a/lib/files.cpp b/lib/files.cpp index ae0a752..f84fcb2 100644 --- a/lib/files.cpp +++ b/lib/files.cpp @@ -428,7 +428,7 @@ int FilesOperation::fischl_getattr(const char *path, struct stat *stbuf, stbuf->st_size = inode.metadata.size; stbuf->st_ino = inode.inode_num; } - perror(std::to_string(inode.inode_num).c_str()); + //perror(std::to_string(inode.inode_num).c_str()); return res; } @@ -754,7 +754,7 @@ int FilesOperation::fischl_write(const char *path, const char *buf, size_t size, // Allocate memory for the new buffer char* buffer = (char*)malloc(size); memcpy(buffer, buf, size); - size_t bytes_write = fs->write(&inode, buffer, size, offset); + ssize_t bytes_write = fs->write(&inode, buffer, size, offset); /*size_t block_index = offset / IO_BLOCK_SIZE; // Starting block index size_t block_offset = offset % IO_BLOCK_SIZE; // Offset within the first block while (bytes_write < size) { @@ -1123,13 +1123,13 @@ int FilesOperation::fischl_rename(const char *old_path, const char *new_path, un int FilesOperation::fischl_truncate(const char *path, off_t offset, struct fuse_file_info *fi) { - (void)fi; - int res = 0; - u_int64_t fh = namei(path); + (void)fi; + int res = 0; + u_int64_t fh = namei(path); - if (fh == -1) { - return -ENOENT; - } + if (fh == -1) { + return -ENOENT; + } INode_Data inode; inode.inode_num = fh; @@ -1137,19 +1137,9 @@ int FilesOperation::fischl_truncate(const char *path, off_t offset, if(!permission_check(W_OK, &inode)){ return -EACCES; } - while(inode.metadata.size > offset + IO_BLOCK_SIZE) { - printf("dealloc, %d\n", inode.metadata.size); - u_int64_t dummy; - fs->deallocate_datablock(&inode, &dummy); - if (inode.metadata.size < IO_BLOCK_SIZE){ - inode.metadata.size = 0; - break; - } - inode.metadata.size-=IO_BLOCK_SIZE; - } - inode.metadata.size = offset; + res = fs->truncate(&inode, offset); fs->inode_manager->save_inode(&inode); - return 0; + return res; } int FilesOperation::fischl_read(const char *path, char *buf, size_t size, @@ -1171,7 +1161,11 @@ int FilesOperation::fischl_read(const char *path, char *buf, size_t size, // Assuming inode is correctly initialized here based on 'path' inode.inode_num = fi->fh; fs->inode_manager->load_inode(&inode); - size_t bytes_read = fs->read(&inode, buf, size, offset); + //printf("OUT READ %llu %llu %llu\n", inode.inode_num, inode.single_indirect_block, inode.double_indirect_block); + ssize_t bytes_read = fs->read(&inode, buf, size, offset); + //printf("BYTES_READ %d\n",int(bytes_read)); + //for (int i = 0; i < bytes_read; i++)printf("%x", buf[i]&0xff); + //printf("\n"); /*size_t len = (inode.metadata.size/IO_BLOCK_SIZE) * IO_BLOCK_SIZE; // Assuming each block is 4096 bytes @@ -1195,37 +1189,7 @@ int FilesOperation::fischl_read(const char *path, char *buf, size_t size, buf, block_buffer); bytes_read += copy_size; block_index++; block_offset = 0; // Only the first block might have a non-zero offset }*/ - - r - eturn bytes_read; // Return the actual number of bytes read -} - -int FilesOperation::fischl_utimens(const char *path, const struct timespec tv[2], struct fuse_file_info *fi){ - (void) fi; - int res = 0; - u_int64_t fh = namei(path); - - if (fh == -1){ - return -ENOENT; - } - - INode_Data inode; - inode.inode_num = fh; - fs->inode_manager->load_inode(&inode); - inode.metadata.access_time = (u_int64_t)tv[0].tv_sec * 1000000000ULL + tv[0].tv_nsec; - inode.metadata.modification_time = (u_int64_t)tv[1].tv_sec * 1000000000ULL + tv[1].tv_nsec; - fs->inode_manager->save_inode(&inode); - return 0; -} - -int FilesOperation::fischl_statfs(const char* path, struct statvfs* stbuf) { - stbuf->f_bsize = 4096; - stbuf->f_blocks = 0; - stbuf->f_bfree = 0; - stbuf->f_files = 0; - stbuf->f_ffree = 0; - stbuf->f_namemax = 256; - return 0; + return bytes_read; // Return the actual number of bytes read } int FilesOperation::fischl_utimens(const char *path, const struct timespec tv[2], struct fuse_file_info *fi){ diff --git a/lib/fischl.cpp b/lib/fischl.cpp index d71689f..b240e73 100644 --- a/lib/fischl.cpp +++ b/lib/fischl.cpp @@ -209,6 +209,11 @@ int fischl(int argc, char *argv[]) } else{ options.H = new RealRawDisk(argv[0]); + char zero_es[IO_BLOCK_SIZE] = {0}; + /*printf("zeroed\n"); + for (int i = 0; i < 200000; i++){ + options.H->write_block(i, zero_es); + }*/ } if(strcmp(argv[1], "l")==0){ options.load = true; @@ -226,6 +231,65 @@ int fischl(int argc, char *argv[]) } options.fsop = new FilesOperation(*options.H, options.fs); + /*INode_Data inode_data; + options.fs->inode_manager->new_inode(1, 2, 3, &inode_data); + + int buf_size = 100000; + int seg_size = 10; + char buf[buf_size]; + + int res; + int num = 1; + + for (u_int64_t i = 0; i < 30 * 1024 * 1024;) { + for (int j = 0; j < buf_size;) { + j += sprintf(&buf[j], "%010d\n", ++num); + } + res = options.fs->write(&inode_data, buf, buf_size, i); + if (res < buf_size) + printf("ERR: %d %d\n", res, i); + i += res; + } + + num = 1; + + printf("done write\n"); + char buf2[buf_size]; + + for (u_int64_t i = 0; i < 30 * 1024 * 1024;) { + for (int j = 0; j < buf_size;) { + j += sprintf(&buf[j], "%010d\n", ++num); + } + res = options.fs->read(&inode_data, buf2, buf_size, i); + if (res < buf_size) + printf("ERR2: %d %d\n", res, i); + i += res; + for (int j = 0; j < res; ++j) { + if (buf[j] != buf2[j]) + printf("err err err: %d %d", buf[j], i); + } + } + + printf("done read\n"); + + num = 1; + + for (u_int64_t i = 0; i < 30 * 1024 * 1024;) { + for (int j = 0; j < buf_size;) { + j += sprintf(&buf[j], "%010d\n", ++num); + } + res = options.fs->read(&inode_data, buf2, buf_size, i); + if (res < buf_size) + printf("ERR2: %d %d\n", res, i); + i += res; + for (int j = 0; j < res; ++j) { + if (buf[j] != buf2[j]) + printf("err err err: %d %d", buf[j], i); + } + } + + printf("done read2\n");*/ + /* Parse options */ diff --git a/lib/fs/fs_file_io.cpp b/lib/fs/fs_file_io.cpp index db8dc37..4182b52 100644 --- a/lib/fs/fs_file_io.cpp +++ b/lib/fs/fs_file_io.cpp @@ -31,6 +31,8 @@ int Fs::sweep_inode_datablocks(INode_Data *inode_data, DatablockOperation *op) { int result; + //printf("SWEEP %llu %llu %llu\n", inode_data->inode_num, inode_data->single_indirect_block, inode_data->double_indirect_block); + 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, @@ -94,6 +96,8 @@ int Fs::sweep_datablocks(u_int64_t *block_num, int indirect_num, } } + //if((*block_num)>30000000000000LL)printf("DIES 1 %llu %d %llu\n", *block_num, indirect_num, start_block_index); + if (indirect_num == 0) { bool delete_block = false; if ((result = op->operation(*block_num, &delete_block)) < 0) @@ -109,6 +113,7 @@ int Fs::sweep_datablocks(u_int64_t *block_num, int indirect_num, if ((*block_num) == 0) { memset(buf, 0, sizeof(buf)); } else { + if ((err = disk->read_block(*block_num, buf)) < 0) return err; } @@ -170,6 +175,7 @@ public: std::min(IO_BLOCK_SIZE - offset, count - bytes_completed); if (block_num != 0) { + if((block_num)>3000000000000LL)printf("DIES 2\n"); if ((err = fs->disk->read_block(block_num, datablock_buf)) < 0) return err; @@ -198,9 +204,11 @@ public: size_t write_size = std::min(IO_BLOCK_SIZE - offset, count - bytes_completed); - if (write_size < IO_BLOCK_SIZE) + if (write_size < IO_BLOCK_SIZE){ + if((block_num)>3000000000000LL)printf("DIES 3\n"); if ((err = fs->disk->read_block(block_num, datablock_buf)) < 0) return err; + } memcpy(&datablock_buf[offset], &buf[bytes_completed], write_size); @@ -227,7 +235,7 @@ public: (*delete_block) = true; return 1; } - + if((block_num)>3000000000000LL)printf("DIES 4\n"); if ((err = fs->disk->read_block(block_num, datablock_buf)) < 0) return err; @@ -281,6 +289,7 @@ ssize_t Fs::read(INode_Data *inode_data, char buf[], size_t count, op.bytes_completed = 0; op.fs = this; + //printf("IN READ %llu %llu %llu\n", inode_data->inode_num, inode_data->single_indirect_block, inode_data->double_indirect_block); if ((err = sweep_inode_datablocks(inode_data, start_block_index, false, &op)) != 0) return err; diff --git a/lib/main.cpp b/lib/main.cpp index 1ac5e82..5474334 100644 --- a/lib/main.cpp +++ b/lib/main.cpp @@ -1,12 +1,6 @@ -#define _GNU_SOURCE - #include "fischl.h" #include "fs.hpp" -#include -#include -#include #include -#include int main(int argc, char *argv[]) { // printf("hello word!"); @@ -40,284 +34,58 @@ int main(int argc, char *argv[]) { // disk->print_block(1597); - // return 0; + /* + int err; - // 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); - - // 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); - - // for (int i = 0; i < BL_SIZE * 3; ++i) - // big_buf[i] = 1; - - // err = fs->write(&inode_data, buf, 4096 * 3, offs); - - // 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); - - // 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); - - // // 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(5120); + 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); - char cwd_buf[PATH_MAX]; - int fd; + disk->print_block(0); + disk->print_block(1); - assert(getcwd(cwd_buf, sizeof(cwd_buf)) != NULL); + int BL_SIZE = 4096 / 8; - fd = open("/tmp", O_TMPFILE | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR); - assert(fd != -1); + u_int64_t buf[BL_SIZE * (56 + 512 + 10)]; - u_int64_t test_start_range = IO_BLOCK_SIZE * 3584; - u_int64_t test_io_range = IO_BLOCK_SIZE * 100; + for (int i = 0; i < BL_SIZE * (56 + 512 + 10); ++i) + buf[i] = (i / BL_SIZE) + 1; - // char ones[test_io_range]; - // memset(ones, 1, test_io_range); - // char twos[test_io_range]; - // memset(twos, 2, test_io_range); + err = fs->write(&inode_data, (char *)buf, 4096 * (56 + 3) + 16 + 8, 0); + fs->inode_manager->save_inode(&inode_data); - 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; - int num; + printf("Write %d", err); - // size_t weird_offset = 6508064; + 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); - for (int i = 0; i < 100000; ++i) { - offset = rand() % test_start_range; + int N = 5; - reads_are_equal = true; - num = rand() % 100; - if (num < 49) - num = 0; - else if (num < 99) - num = 1; - else - num = 2; + u_int64_t buf2[4096] = {0}; + err = fs->read(&inode_data, (char *)buf2, (8 * N), 4096 - 8 - 8); - if (i % 100 == 0) - printf("%d\n", i); + printf("\n\nREAD: %d\n", err); + for (int i = 0; i < N; ++i) + printf("%d ", buf2[i]); + printf("\n");*/ - switch (num) { - case 0: - count = rand() % test_io_range; - 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); - 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); - for (size_t j = 0; j < count; ++j) - if (test_read_buf[i] != reference_read_buf[i]) { - reads_are_equal = false; - break; - } - break; - case 2: - // if (offset <= weird_offset) - // printf("truncate: length=%d\n", offset); - test_res = fs->truncate(&inode_data, offset); - ref_res = ftruncate(fd, offset); - break; - } + fischl(argc, argv); - // printf("test_res=%d, ref_res=%d\n", test_res, ref_res); - assert(test_res == ref_res); - if (!reads_are_equal && count > 0) { - int prev_test = test_read_buf[0], prev_ref = reference_read_buf[0], - same_count = 1; - for (size_t j = 1; j < count; ++j) { - u_int64_t byte_index = (j + offset); - if (byte_index % IO_BLOCK_SIZE == 0) - printf("Block: %d\n", byte_index / IO_BLOCK_SIZE); - if (prev_test != test_read_buf[j] || - prev_ref != reference_read_buf[j]) { - printf("rt %d %d%s\n", prev_ref, prev_test, - (prev_test != prev_ref) - ? " -----DIFF----- -----DIFF----- -----DIFF-----" - : ""); - printf("^^^^ same for %d bytes ending at %d, starting at %d ^^^^\n", - same_count, byte_index, byte_index - same_count); - prev_test = test_read_buf[j]; - prev_ref = reference_read_buf[j]; - same_count = 1; - } else { - same_count++; - } - } - printf("rt %d %d%s\n", prev_test, prev_test, - (prev_test != prev_ref) - ? " -----DIFF----- -----DIFF----- -----DIFF-----" - : ""); - printf("^^^^ same for %d bytes ^^^^\n", same_count); - } - assert(reads_are_equal); - } - - // 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 diff --git a/lib/rawdisk.cpp b/lib/rawdisk.cpp index 6a1a6e5..f6203d0 100644 --- a/lib/rawdisk.cpp +++ b/lib/rawdisk.cpp @@ -43,6 +43,8 @@ RealRawDisk::RealRawDisk(const char *directory) exit(1); } + //diskSize = 27648 * IO_BLOCK_SIZE; + // Calculate the size in bytes numSectors = diskSize / 512; // Assuming a sector size of 512 bytes @@ -61,12 +63,16 @@ int RealRawDisk::read_block(u_int64_t block_number, char *buffer) { u_int64_t offset = block_number * IO_BLOCK_SIZE; if (lseek(fd, offset, SEEK_SET) == (u_int64_t)-1) { + printf("LSEEK ERROR %llu %llu\n", block_number, offset); perror("Error seeking to offset"); return -1; } // TODO: this is incorrect ssize_t bytesRead = read(fd, buffer, IO_BLOCK_SIZE); + //printf("READ BLOCK: %llu\n", block_number); + //for (int i = 0; i < IO_BLOCK_SIZE; i++)printf("%x", buffer[i]&0xff); + //printf("\n"); if (bytesRead < IO_BLOCK_SIZE) { perror("Error reading from device"); return -1;