added errno

This commit is contained in:
Connor 2023-12-05 23:13:05 -08:00
parent 6dc6f36d27
commit 8d2e8cd750
8 changed files with 249 additions and 114 deletions

View File

@ -7,7 +7,6 @@
#include "fs_constants.hpp"
#include "rawdisk.hpp"
// TEMP:
class DatablockOperation;
class Fs {

View File

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

View File

@ -2,6 +2,7 @@
#define FS_CONSTANTS_HPP
#include <algorithm>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <linux/fs.h>
@ -11,6 +12,7 @@
#include <sys/ioctl.h>
#include <unistd.h>
#define IO_BLOCK_SIZE 4096
#define INDIRECT_BLOCKS 512

View File

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

View File

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

View File

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

View File

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

View File

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