iloveos/lib/rawdisk.cpp
2023-12-05 23:13:05 -08:00

144 lines
3.6 KiB
C++

#include "fs.hpp"
void RawDisk::print_block(u_int64_t block_number) {
const int nums_per_line = 64;
char buf[IO_BLOCK_SIZE];
u_int64_t num;
if (read_block(block_number, buf) < 0) {
perror("Error printing datablock");
return;
}
printf("\nBlock %lu:\n", block_number);
for (int i = 0; i < IO_BLOCK_SIZE; i += sizeof(u_int64_t)) {
num = 0;
for (int j = 0; j < 8; j++)
num |= ((u_int64_t)(unsigned char)buf[i + j]) << (8 * j);
printf("%lu ", num);
if ((i / sizeof(u_int64_t)) % nums_per_line == nums_per_line - 1)
printf("\n");
}
}
RealRawDisk::RealRawDisk(const char *directory, u_int64_t _diskSize)
: fd(-1), dir(nullptr), numSectors(0) {
dir = directory;
diskSize = 0;
/*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);
}
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
numSectors = diskSize / 512; // Assuming a sector size of 512 bytes
printf("====Initializing RawDisk====\n");
printf("Number of sectors: %lu\n", numSectors);
printf("Disk size (in bytes): %lu\n", diskSize);
}
RealRawDisk::~RealRawDisk() {
if (fd != -1) {
close(fd);
}
}
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) {
perror("Error seeking to offset");
errno = EIO;
return -1;
}
// TODO: this is incorrect
ssize_t bytesRead = read(fd, buffer, IO_BLOCK_SIZE);
if (bytesRead < IO_BLOCK_SIZE) {
perror("Error reading from device");
errno = EIO;
return -1;
}
return 0;
}
int RealRawDisk::write_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) {
perror("Error seeking to offset");
errno = EIO;
return -1;
}
// TODO: this is incorrect
ssize_t bytesWritten = write(fd, buffer, IO_BLOCK_SIZE);
if (bytesWritten < IO_BLOCK_SIZE) {
perror("Error writing to device");
errno = EIO;
return -1;
}
return 0;
}
FakeRawDisk::FakeRawDisk(u_int64_t num_blocks) {
diskSize = num_blocks * IO_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): %lu\n", diskSize);
perror("!!! USING FAKE RawDisk - THIS IS FOR TESTING ONLY !!!");
}
FakeRawDisk::~FakeRawDisk() { delete[] disk; }
int FakeRawDisk::read_block(u_int64_t block_number, char *buffer) {
u_int64_t offset = block_number * IO_BLOCK_SIZE;
if (offset + IO_BLOCK_SIZE > diskSize) {
perror("Error reading past fake disk size");
errno = EIO;
return -1;
}
memcpy(buffer, &disk[offset], IO_BLOCK_SIZE);
return 0;
}
int FakeRawDisk::write_block(u_int64_t block_number, char *buffer) {
u_int64_t offset = block_number * IO_BLOCK_SIZE;
if (offset + IO_BLOCK_SIZE > diskSize) {
perror("Error writing past fake disk size");
errno = EIO;
return -1;
}
memcpy(&disk[offset], buffer, IO_BLOCK_SIZE);
return 0;
}