added in core fake rawdisk

This commit is contained in:
Connor 2023-11-14 22:55:09 -08:00
parent 8c263f02b1
commit 3ee1647e00
6 changed files with 178 additions and 128 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -1,15 +1,13 @@
#include "fs.hpp"
template <typename T> T write_int(T num, char buf[])
{
template <typename T> 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 <typename T> T read_int(T *num, char buf[])
{
template <typename T> T read_int(T *num, char buf[]) {
size_t i = 0;
T temp = 0;
for (; i < sizeof(T); ++i) {

View File

@ -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;
}

124
lib/rawdisk.cpp Normal file
View File

@ -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;
}
};