From 8d2e8cd75057d97848d4d9aa4b9073b6e05c6f77 Mon Sep 17 00:00:00 2001 From: Connor Date: Tue, 5 Dec 2023 23:13:05 -0800 Subject: [PATCH] added errno --- include/fs.hpp | 1 - include/fs/fs_data_types.hpp | 4 + include/fs_constants.hpp | 2 + include/rawdisk.hpp | 2 +- lib/fs/datablock_manager.cpp | 8 +- lib/fs/fs_file_io.cpp | 33 +++- lib/main.cpp | 291 +++++++++++++++++++++++------------ lib/rawdisk.cpp | 22 ++- 8 files changed, 249 insertions(+), 114 deletions(-) diff --git a/include/fs.hpp b/include/fs.hpp index 3a420aa..b2f941a 100644 --- a/include/fs.hpp +++ b/include/fs.hpp @@ -7,7 +7,6 @@ #include "fs_constants.hpp" #include "rawdisk.hpp" -// TEMP: class DatablockOperation; class Fs { diff --git a/include/fs/fs_data_types.hpp b/include/fs/fs_data_types.hpp index 134db85..d2d1480 100644 --- a/include/fs/fs_data_types.hpp +++ b/include/fs/fs_data_types.hpp @@ -39,6 +39,10 @@ public: #define NUMBER_OF_DIRECT_BLOCKS \ (((INODE_SIZE - NUMBER_OF_METADATA_BYTES) / sizeof(u_int64_t)) - 3) +#define FILE_SIZE_MAX \ + (IO_BLOCK_SIZE * (NUMBER_OF_DIRECT_BLOCKS + INDIRECT_BLOCKS + \ + (INDIRECT_BLOCKS * INDIRECT_BLOCKS) + \ + (INDIRECT_BLOCKS * INDIRECT_BLOCKS * INDIRECT_BLOCKS))) u_int64_t single_indirect_block, double_indirect_block, triple_indirect_block; u_int64_t direct_blocks[NUMBER_OF_DIRECT_BLOCKS]; diff --git a/include/fs_constants.hpp b/include/fs_constants.hpp index fb3a53c..239ed55 100644 --- a/include/fs_constants.hpp +++ b/include/fs_constants.hpp @@ -2,6 +2,7 @@ #define FS_CONSTANTS_HPP #include +#include #include #include #include @@ -11,6 +12,7 @@ #include #include + #define IO_BLOCK_SIZE 4096 #define INDIRECT_BLOCKS 512 diff --git a/include/rawdisk.hpp b/include/rawdisk.hpp index ebbea1a..c776a4a 100644 --- a/include/rawdisk.hpp +++ b/include/rawdisk.hpp @@ -19,7 +19,7 @@ public: const char *dir; u_int64_t numSectors; - RealRawDisk(const char *directory); + RealRawDisk(const char *directory, u_int64_t _diskSize = 0); ~RealRawDisk(); int read_block(u_int64_t block_number, char *buffer) override; diff --git a/lib/fs/datablock_manager.cpp b/lib/fs/datablock_manager.cpp index 192f463..2d8ff51 100644 --- a/lib/fs/datablock_manager.cpp +++ b/lib/fs/datablock_manager.cpp @@ -52,8 +52,10 @@ int DataBlock_Manager_Bitmap::new_datablock(u_int64_t *block_num) { char zero_buf[IO_BLOCK_SIZE] = {0}; if (bitmap_block_num < block_segment_start || - bitmap_block_num >= block_segment_end) + bitmap_block_num >= block_segment_end) { + perror("Error with new_datablock freelist head\n"); return -1; + } if ((err = fs->disk->read_block(bitmap_block_num, bitmap.buf)) < 0) return err; @@ -64,8 +66,10 @@ int DataBlock_Manager_Bitmap::new_datablock(u_int64_t *block_num) { u_int64_t relative_block_num = bitmap.claim_relative_block(); - if (relative_block_num == 0) + if (relative_block_num == 0) { + errno = ENOSPC; return -1; + } u_int64_t block_num_ = relative_block_num + bitmap_block_num; diff --git a/lib/fs/fs_file_io.cpp b/lib/fs/fs_file_io.cpp index db8dc37..5cf7a30 100644 --- a/lib/fs/fs_file_io.cpp +++ b/lib/fs/fs_file_io.cpp @@ -282,7 +282,7 @@ ssize_t Fs::read(INode_Data *inode_data, char buf[], size_t count, op.fs = this; if ((err = sweep_inode_datablocks(inode_data, start_block_index, false, - &op)) != 0) + &op)) < 0) return err; return op.bytes_completed; @@ -302,10 +302,15 @@ ssize_t Fs::write(INode_Data *inode_data, const char buf[], size_t count, op.bytes_completed = 0; 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; + if (err > 1) { + errno = EFBIG; + return -1; + } + inode_data->metadata.size = std::max(offset + op.bytes_completed, inode_data->metadata.size); @@ -315,6 +320,16 @@ ssize_t Fs::write(INode_Data *inode_data, const char buf[], size_t count, int Fs::truncate(INode_Data *inode_data, size_t length) { int err; + if (length > FILE_SIZE_MAX) { + errno = EFBIG; + return -1; + } + + if (length < 0) { + errno = EINVAL; + return -1; + } + u_int64_t start_block_index = length / IO_BLOCK_SIZE; size_t internal_offset = length - (start_block_index * IO_BLOCK_SIZE); @@ -334,8 +349,10 @@ int Fs::truncate(INode_Data *inode_data, size_t length) { ssize_t Fs::lseek_next_data(INode_Data *inode_data, size_t offset) { int err; - if (offset >= inode_data->metadata.size) + if (offset >= inode_data->metadata.size) { + errno = ENXIO; return -1; + } u_int64_t start_block_index = offset / IO_BLOCK_SIZE; size_t internal_offset = offset - (start_block_index * IO_BLOCK_SIZE); @@ -350,8 +367,10 @@ ssize_t Fs::lseek_next_data(INode_Data *inode_data, size_t offset) { &op)) < 0) return err; - if (op.bytes_completed >= inode_data->metadata.size) + if (op.bytes_completed >= inode_data->metadata.size) { + errno = ENXIO; return -1; + } return op.bytes_completed; } @@ -359,8 +378,10 @@ ssize_t Fs::lseek_next_data(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) + if (offset >= inode_data->metadata.size) { + errno = ENXIO; return -1; + } u_int64_t start_block_index = offset / IO_BLOCK_SIZE; size_t internal_offset = offset - (start_block_index * IO_BLOCK_SIZE); diff --git a/lib/main.cpp b/lib/main.cpp index 1ac5e82..14dd312 100644 --- a/lib/main.cpp +++ b/lib/main.cpp @@ -170,121 +170,126 @@ 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(5120); - Fs *fs = new Fs(disk); - fs->format(); + // int disk_size = 9216; + // RawDisk *disk = + // new RealRawDisk("/home/connor/fakeDisk", disk_size * IO_BLOCK_SIZE); + // Fs *fs = new Fs(disk); + // fs->format(); - 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); - char cwd_buf[PATH_MAX]; - int fd; + // char cwd_buf[PATH_MAX]; + // int fd; - assert(getcwd(cwd_buf, sizeof(cwd_buf)) != NULL); + // assert(getcwd(cwd_buf, sizeof(cwd_buf)) != NULL); - fd = open("/tmp", O_TMPFILE | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR); - assert(fd != -1); + // fd = open("/tmp", O_TMPFILE | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR); + // assert(fd != -1); - u_int64_t test_start_range = IO_BLOCK_SIZE * 3584; - u_int64_t test_io_range = IO_BLOCK_SIZE * 100; + // u_int64_t test_start_range = IO_BLOCK_SIZE * 7900; + // u_int64_t test_io_range = IO_BLOCK_SIZE * 200; // char ones[test_io_range]; - // memset(ones, 1, test_io_range); + // memset(ones, '1', test_io_range); // char twos[test_io_range]; - // memset(twos, 2, test_io_range); + // memset(twos, '2', test_io_range); - 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; + // 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; - // size_t weird_offset = 6508064; + // // size_t weird_offset = 6508064; - for (int i = 0; i < 100000; ++i) { - offset = rand() % test_start_range; + // 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; + // count = rand() % test_io_range; - if (i % 100 == 0) - printf("%d\n", i); + // reads_are_equal = true; + // num = rand() % 100; + // if (num < 49) + // num = 0; + // else if (num < 99) + // num = 1; + // else + // num = 2; - 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; - } + // if (i % 100 == 0) + // printf("%d\n", i); - // printf("test_res=%d, ref_res=%d\n", test_res, ref_res); - assert(test_res == ref_res); + // switch (num) { + // case 0: + // 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); + // case 1: + // // 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; + // } - 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); - } + // if (test_res != ref_res) + // printf("test_res=%d, ref_res=%d, offset=%d, count=%d, type=%d\n", + // test_res, ref_res, offset, count, num); + // assert(test_res == ref_res); - assert(reads_are_equal); - } + // 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); @@ -320,4 +325,94 @@ int main(int argc, char *argv[]) { // return -1; // } // } + // int disk_size = 5120; + // RawDisk *disk = new FakeRawDisk(5120); + // Fs *fs = new Fs(disk); + // char bad_buf[IO_BLOCK_SIZE]; + // for (int i = 0; i < IO_BLOCK_SIZE; ++i) + // bad_buf[i] = rand(); + // for (int i = 0; i < disk_size;); + // fs->format(); + + // INode_Data inode_data; + // fs->inode_manager->new_inode(1, 2, 3, &inode_data); + + int disk_size = 9216; + RawDisk *disk = + new RealRawDisk("/home/connor/fakeDisk", disk_size * IO_BLOCK_SIZE); + Fs *fs = new Fs(disk); + fs->format(); + + INode_Data inode_data; + fs->inode_manager->new_inode(1, 2, 3, &inode_data); + + int buf_size = 100000; + int seg_size = 10; + char buf[buf_size * 3]; + + int res; + int num = 1; + + for (u_int64_t i = 0; i < 30 * 1024 * 1024;) { + for (int j = 0; j < buf_size / 2 + 10;) { + j += sprintf(&buf[j], "%09d\n", ++num); + } + res = fs->write(&inode_data, buf, buf_size / 2 + 10, i); + if (res < buf_size / 2 + 10) + printf("ERR: %d %d\n", res, i); + i += res; + } + + num = 1; + + int k = 0; + int num_p = 10; + + printf("done write\n"); + char buf2[buf_size * 3]; + + for (u_int64_t i = 0; i < 30 * 1024 * 1024;) { + for (int j = 0; j < buf_size * 3;) { + j += sprintf(&buf[j], "%09d\n", ++num); + } + res = fs->read(&inode_data, buf2, buf_size * 3, i); + if (res < buf_size * 3) + 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 r%c t%c\n", i, j, buf[j], buf2[j]); + ++k; + if (k > num_p) + break; + } + } + if (k > num_p) + break; + } + + printf("done read\n"); + + num = 1; + k = 0; + + for (u_int64_t i = 0; i < 30 * 1024 * 1024;) { + for (int j = 0; j < buf_size * 3;) { + j += sprintf(&buf[j], "%09d\n", ++num); + } + res = fs->read(&inode_data, buf2, buf_size * 3, i); + if (res < buf_size * 3) + printf("ERR2: %d %d\n", res, i); + i += res; + for (int j = 0; j < res; ++j) { + if (buf[j] != buf2[j]) { + printf("ERR ERR ERR2: %d %d r%c t%c\n", i, j, buf[j], buf2[j]); + ++k; + if (k > num_p) + return -1; + } + } + } + + printf("done read2\n"); } \ No newline at end of file diff --git a/lib/rawdisk.cpp b/lib/rawdisk.cpp index 6a1a6e5..ed815f0 100644 --- a/lib/rawdisk.cpp +++ b/lib/rawdisk.cpp @@ -21,7 +21,7 @@ void RawDisk::print_block(u_int64_t block_number) { } } -RealRawDisk::RealRawDisk(const char *directory) +RealRawDisk::RealRawDisk(const char *directory, u_int64_t _diskSize) : fd(-1), dir(nullptr), numSectors(0) { dir = directory; diskSize = 0; @@ -36,11 +36,15 @@ RealRawDisk::RealRawDisk(const char *directory) exit(1); } - // Use ioctl with BLKGETSIZE to get the number of sectors - if (ioctl(fd, BLKGETSIZE64, &diskSize) == -1) { - perror("Error getting disk size"); - close(fd); - exit(1); + if (_diskSize == 0) { + // Use ioctl with BLKGETSIZE to get the number of sectors + if (ioctl(fd, BLKGETSIZE64, &diskSize) == -1) { + perror("Error getting disk size"); + close(fd); + exit(1); + } + } else { + diskSize = _diskSize; } // Calculate the size in bytes @@ -62,6 +66,7 @@ int RealRawDisk::read_block(u_int64_t block_number, char *buffer) { if (lseek(fd, offset, SEEK_SET) == (u_int64_t)-1) { perror("Error seeking to offset"); + errno = EIO; return -1; } @@ -69,6 +74,7 @@ int RealRawDisk::read_block(u_int64_t block_number, char *buffer) { ssize_t bytesRead = read(fd, buffer, IO_BLOCK_SIZE); if (bytesRead < IO_BLOCK_SIZE) { perror("Error reading from device"); + errno = EIO; return -1; } @@ -80,6 +86,7 @@ int RealRawDisk::write_block(u_int64_t block_number, char *buffer) { if (lseek(fd, offset, SEEK_SET) == (u_int64_t)-1) { perror("Error seeking to offset"); + errno = EIO; return -1; } @@ -87,6 +94,7 @@ int RealRawDisk::write_block(u_int64_t block_number, char *buffer) { ssize_t bytesWritten = write(fd, buffer, IO_BLOCK_SIZE); if (bytesWritten < IO_BLOCK_SIZE) { perror("Error writing to device"); + errno = EIO; return -1; } @@ -112,6 +120,7 @@ int FakeRawDisk::read_block(u_int64_t block_number, char *buffer) { if (offset + IO_BLOCK_SIZE > diskSize) { perror("Error reading past fake disk size"); + errno = EIO; return -1; } @@ -125,6 +134,7 @@ int FakeRawDisk::write_block(u_int64_t block_number, char *buffer) { if (offset + IO_BLOCK_SIZE > diskSize) { perror("Error writing past fake disk size"); + errno = EIO; return -1; }