From 3ee1647e00808de76e033985fd498602abadb9d6 Mon Sep 17 00:00:00 2001 From: Connor Date: Tue, 14 Nov 2023 22:55:09 -0800 Subject: [PATCH] added in core fake rawdisk --- include/rawdisk.hpp | 79 +-------------------- lib/fs/datablock_allocator.cpp | 5 +- lib/fs/fs.cpp | 19 ++--- lib/fs/fs_data_types.cpp | 6 +- lib/fs/inode_allocator.cpp | 73 ++++++++++--------- lib/rawdisk.cpp | 124 +++++++++++++++++++++++++++++++++ 6 files changed, 178 insertions(+), 128 deletions(-) create mode 100644 lib/rawdisk.cpp diff --git a/include/rawdisk.hpp b/include/rawdisk.hpp index 9922e81..01c5a33 100644 --- a/include/rawdisk.hpp +++ b/include/rawdisk.hpp @@ -12,84 +12,11 @@ #define BLOCK_SIZE 4096 class RawDisk { - - int fd; - const char *dir; - u_int64_t numSectors; +public: u_int64_t diskSize; -public: - RawDisk(const char *directory) - : fd(-1), dir(nullptr), numSectors(0), diskSize(0) { - dir = directory; - /*dir = strdup("/dev/vdc"); - numSectors = 62914560; - diskSize = 32212254720;*/ - - // Open the block device (replace /dev/sdX with the actual device) - fd = open(dir, O_RDWR); // Allow read and write - if (fd == -1) { - perror("Error opening device"); - 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); - } - - // Calculate the size in bytes - 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); - } - - ~RawDisk() { - if (fd != -1) { - close(fd); - } - } - - int read_block(u_int64_t block_number, char *buffer) { - u_int64_t offset = block_number * BLOCK_SIZE; - - if (lseek(fd, offset, SEEK_SET) == (u_int64_t)-1) { - perror("Error seeking to offset"); - return -1; - } - - // TODO: this is incorrect - ssize_t bytesRead = read(fd, buffer, BLOCK_SIZE); - if (bytesRead < BLOCK_SIZE) { - perror("Error reading from device"); - return -1; - } - - return 0; - } - - // Write a specified number of bytes at a given byte offset - int write_block(u_int64_t block_number, char *buffer) { - u_int64_t offset = block_number * BLOCK_SIZE; - - if (lseek(fd, offset, SEEK_SET) == (u_int64_t)-1) { - perror("Error seeking to offset"); - return -1; - } - - // TODO: this is incorrect - ssize_t bytesWritten = write(fd, buffer, BLOCK_SIZE); - if (bytesWritten < BLOCK_SIZE) { - perror("Error writing to device"); - return -1; - } - - return 0; - } + virtual int read_block(u_int64_t block_number, char *buffer) = 0; + virtual int write_block(u_int64_t block_number, char *buffer) = 0; }; #endif \ No newline at end of file diff --git a/lib/fs/datablock_allocator.cpp b/lib/fs/datablock_allocator.cpp index d8ea8a8..022f97b 100644 --- a/lib/fs/datablock_allocator.cpp +++ b/lib/fs/datablock_allocator.cpp @@ -107,10 +107,9 @@ int DataBlock_Allocator_Bitmap::free_datablock(u_int64_t block_num) { if ((err = disk->write_block(bitmap_block_num, bitmap.buf)) < 0) return err; - if (update_freelist) { + if (update_freelist) if ((err = fs->save_free_list_head(bitmap_block_num)) < 0) return err; - } return 0; @@ -132,6 +131,6 @@ int DataBlock_Allocator_Bitmap::format() { if ((err = disk->write_block(i, buf)) < 0) return err; if ((err = fs->save_free_list_head(block_segment_start)) < 0) - return err; + return err; return 0; } \ No newline at end of file diff --git a/lib/fs/fs.cpp b/lib/fs/fs.cpp index 9beb2df..8e9d642 100644 --- a/lib/fs/fs.cpp +++ b/lib/fs/fs.cpp @@ -47,8 +47,8 @@ int Fs::save_free_list_head(u_int64_t new_free_list_head) { int err; superblock.free_list_head = new_free_list_head; if ((err = fs->store_superblock()) < 0) { - superblock.free_list_head = temp; - return err; + superblock.free_list_head = temp; + return err; } return 0; } @@ -57,8 +57,8 @@ int Fs::save_inode_list_head(u_int64_t new_inode_list_head) { int err; superblock.inode_list_head = new_inode_list_head; if ((err = fs->store_superblock()) < 0) { - superblock.inode_list_head = temp; - return err; + superblock.inode_list_head = temp; + return err; } return 0; } @@ -70,14 +70,15 @@ int Fs::load_inode(INode_Data *inode_data) { u_int64_t block_num = inode_allocator.get_block_num(inode_data->inode_num); if (block_num == 0) return -1; - u_int64_t block_offset = inode_allocator.get_block_offset(inode_data->inode_num); + u_int64_t block_offset = + inode_allocator.get_block_offset(inode_data->inode_num); if ((err = disk->read_block(block_num, buf)) < 0) return err; inode_data->deserialize(&buf[block_offset]); - return 0; + return 0; } int Fs::save_inode(INode_Data *inode_data) { char buf[BLOCK_SIZE]; @@ -86,14 +87,16 @@ int Fs::save_inode(INode_Data *inode_data) { u_int64_t block_num = inode_allocator.get_block_num(inode_data->inode_num); if (block_num == 0) return -1; - u_int64_t block_offset = inode_allocator.get_block_offset(inode_data->inode_num); + u_int64_t block_offset = + inode_allocator.get_block_offset(inode_data->inode_num); if ((err = disk->read_block(block_num, buf)) < 0) return err; inode_data->serialize(&buf[block_offset]); - if ((err = disk->write_block(block_num, buf)) < 0) return err; + if ((err = disk->write_block(block_num, buf)) < 0) + return err; return 0; } \ No newline at end of file diff --git a/lib/fs/fs_data_types.cpp b/lib/fs/fs_data_types.cpp index 9fa5794..32004f2 100644 --- a/lib/fs/fs_data_types.cpp +++ b/lib/fs/fs_data_types.cpp @@ -1,15 +1,13 @@ #include "fs.hpp" -template T write_int(T num, char buf[]) -{ +template T write_int(T num, char buf[]) { size_t i = 0; for (; i < sizeof(T); ++i) buf[i] = (char)(num >> (i * 8)); return i; } -template T read_int(T *num, char buf[]) -{ +template T read_int(T *num, char buf[]) { size_t i = 0; T temp = 0; for (; i < sizeof(T); ++i) { diff --git a/lib/fs/inode_allocator.cpp b/lib/fs/inode_allocator.cpp index 36b8475..df02930 100644 --- a/lib/fs/inode_allocator.cpp +++ b/lib/fs/inode_allocator.cpp @@ -9,8 +9,7 @@ INode_Allocator::INode_Allocator(Fs *fs, u_int64_t block_segment_start, } u_int64_t INode_Allocator::get_block_num(u_int64_t inode_num) { - u_int64_t block_num = - block_segment_start + (inode_num / INODES_PER_BLOCK); + u_int64_t block_num = block_segment_start + (inode_num / INODES_PER_BLOCK); if (block_num >= block_segment_end) return 0; return block_num; @@ -25,21 +24,21 @@ int INode_Allocator_Freelist::new_inode(u_int64_t uid, u_int64_t gid, char buf[BLOCK_SIZE]; int err; u_int64_t inode_num = fs->superblock.inode_list_head; - if(inode_num > max_num_inodes) + if (inode_num > max_num_inodes) return -1; - + u_int64_t block_num = get_block_num(inode_num); - if(block_num == 0) + if (block_num == 0) return -1; if ((err = disk->read_block(block_num, buf)) < 0) - return err; - + return err; + u_int64_t new_inode_list_head = 0; read_u64(&new_inode_list_head, buf); if ((err = fs->save_inode_list_head(new_inode_list_head)) < 0) - return err; + return err; (*inode_data) = INode_Data(inode_num); @@ -49,47 +48,47 @@ int INode_Allocator_Freelist::new_inode(u_int64_t uid, u_int64_t gid, // It is debatable if this function should do this: if ((err = fs->save_inode(inode_data)) < 0) { - inode_data->inode_num = 0xFFFFFFFFFFFFFFFF; - return err; + inode_data->inode_num = 0xFFFFFFFFFFFFFFFF; + return err; } return 0; } -int INode_Allocator_Freelist::free_inode(INode_Data *inode_data) { - char buf[BLOCK_SIZE]; - int err; +int INode_Allocator_Freelist::free_inode(INode_Data *inode_data) { + char buf[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); + 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 (block_num == 0) + return -1; - if ((err = disk->read_block(block_num, buf)) < 0) - return err; + if ((err = disk->read_block(block_num, buf)) < 0) + return err; - write_u64(fs->superblock.inode_list_head, &buf[block_offset]); + write_u64(fs->superblock.inode_list_head, &buf[block_offset]); - if ((err = disk->write_block(block_num, buf)) < 0) - return err; + if ((err = disk->write_block(block_num, buf)) < 0) + return err; - if ((err = fs->save_inode_list_head(inode_data->inode_num)) < 0) - return err; + if ((err = fs->save_inode_list_head(inode_data->inode_num)) < 0) + return err; - return 0; + return 0; } int INode_Allocator_Freelist::format() { - char buf[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 = disk->write_block(i, buf)) < 0) - return err; - } - if ((err = fs->save_inode_list_head(0)) < 0) + char buf[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 = disk->write_block(i, buf)) < 0) return err; - return 0; - } + } + if ((err = fs->save_inode_list_head(0)) < 0) + return err; + return 0; +} diff --git a/lib/rawdisk.cpp b/lib/rawdisk.cpp new file mode 100644 index 0000000..cff45f3 --- /dev/null +++ b/lib/rawdisk.cpp @@ -0,0 +1,124 @@ +#include "rawdisk.hpp" + +class RealRawDisk : RawDisk { +public: + int fd; + const char *dir; + u_int64_t numSectors; + + RealRawDisk(const char *directory) + : fd(-1), dir(nullptr), numSectors(0), diskSize(0) { + dir = directory; + /*dir = strdup("/dev/vdc"); + numSectors = 62914560; + diskSize = 32212254720;*/ + + // Open the block device (replace /dev/sdX with the actual device) + fd = open(dir, O_RDWR); // Allow read and write + if (fd == -1) { + perror("Error opening device"); + 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); + } + + // Calculate the size in bytes + 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); + } + + ~RealRawDisk() { + if (fd != -1) { + close(fd); + } + } + + int read_block(u_int64_t block_number, char *buffer) { + u_int64_t offset = block_number * BLOCK_SIZE; + + if (lseek(fd, offset, SEEK_SET) == (u_int64_t)-1) { + perror("Error seeking to offset"); + return -1; + } + + // TODO: this is incorrect + ssize_t bytesRead = read(fd, buffer, BLOCK_SIZE); + if (bytesRead < BLOCK_SIZE) { + perror("Error reading from device"); + return -1; + } + + return 0; + } + + int write_block(u_int64_t block_number, char *buffer) { + u_int64_t offset = block_number * BLOCK_SIZE; + + if (lseek(fd, offset, SEEK_SET) == (u_int64_t)-1) { + perror("Error seeking to offset"); + return -1; + } + + // TODO: this is incorrect + ssize_t bytesWritten = write(fd, buffer, BLOCK_SIZE); + if (bytesWritten < BLOCK_SIZE) { + perror("Error writing to device"); + return -1; + } + + return 0; + } +}; + +class FakeRawDisk : RawDisk { +public: + char *disk; + + FakeRawDisk(u_int64_t num_blocks) { + disksize = num_blocks * BLOCK_SIZE; + disk = new char[disksize]; + if (disk == nullptr) { + perror("Error allocating fake disk"); + exit(1); + } + printf("====Initializing FAKE RawDisk====\n"); + printf("FAKE Disk size (in bytes): %llu\n", diskSize); + perror("!!! USING FAKE RawDisk - THIS IS FOR TESTING ONLY !!!"); + } + + ~FakeRawDisk() { delete[] disk; } + + int read_block(u_int64_t block_number, char *buffer) { + u_int64_t offset = block_number * BLOCK_SIZE; + + if (offset + BLOCK_SIZE > diskSize) { + perror("Error reading past fake disk size"); + return -1; + } + + memcpy(buffer, &disk[offset], BLOCK_SIZE); + + return 0; + } + + int write_block(u_int64_t block_number, char *buffer) { + u_int64_t offset = block_number * BLOCK_SIZE; + + if (offset + BLOCK_SIZE > diskSize) { + perror("Error writing past fake disk size"); + return -1; + } + + memcpy(&disk[offset], buffer, BLOCK_SIZE); + + return 0; + } +}; \ No newline at end of file