added extra file io

This commit is contained in:
Connor 2023-11-29 16:42:26 -08:00
parent cadf11b857
commit 4dcb74d29e
10 changed files with 184 additions and 159 deletions

View File

@ -15,7 +15,6 @@ add_executable(fischl
lib/rawdisk.cpp lib/rawdisk.cpp
lib/fs/datablock_manager.cpp lib/fs/datablock_manager.cpp
lib/fs/fs_data_types.cpp lib/fs/fs_data_types.cpp
lib/fs/fs_resize.cpp
lib/fs/fs_file_io.cpp lib/fs/fs_file_io.cpp
lib/fs/fs.cpp lib/fs/fs.cpp
lib/fs/inode_manager.cpp lib/fs/inode_manager.cpp

View File

@ -15,20 +15,12 @@ public:
Fs(RawDisk *disk); Fs(RawDisk *disk);
~Fs(); ~Fs();
int allocate_datablock(INode_Data *inode_data, u_int64_t *datablock_num);
int deallocate_datablock(INode_Data *inode_data, u_int64_t *datablock_num);
ssize_t read(INode_Data *inode_data, char buf[], size_t count, size_t offset); ssize_t read(INode_Data *inode_data, char buf[], size_t count, size_t offset);
ssize_t write(INode_Data *inode_data, char buf[], size_t count, ssize_t write(INode_Data *inode_data, char buf[], size_t count,
size_t offset); size_t offset);
int truncate(INode_Data *inode_data, size_t length);
int sweep_inode_datablocks(INode_Data *inode_data, ssize_t lseek_next_data(INode_Data *inode_data, size_t offset);
u_int64_t start_block_index, bool allocate, ssize_t lseek_next_hole(INode_Data *inode_data, size_t offset);
DatablockOperation *op);
int sweep_datablocks(u_int64_t *block_num, int indirect_num,
u_int64_t start_block_index, bool allocate,
DatablockOperation *op);
int format(); int format();
@ -44,8 +36,13 @@ public:
int save_free_list_head(u_int64_t new_free_list_head); int save_free_list_head(u_int64_t new_free_list_head);
int save_inode_list_head(u_int64_t new_inode_list_head); int save_inode_list_head(u_int64_t new_inode_list_head);
int allocate_indirect(u_int64_t *storage, int n, u_int64_t *datablock_num); int sweep_inode_datablocks(INode_Data *inode_data,
int deallocate_indirect(u_int64_t *storage, int n, u_int64_t *datablock_num); u_int64_t start_block_index, bool allocate,
DatablockOperation *op);
int sweep_datablocks(u_int64_t *block_num, int indirect_num,
u_int64_t start_block_index, bool allocate,
DatablockOperation *op);
}; };
#endif #endif

View File

@ -14,7 +14,6 @@
#define IO_BLOCK_SIZE 4096 #define IO_BLOCK_SIZE 4096
#define NUM_INODE_BLOCKS 1023 #define NUM_INODE_BLOCKS 1023
#define NUM_BLOCKS 2048
#define INODE_SIZE 512 #define INODE_SIZE 512

View File

@ -1,4 +1,5 @@
#include "fs.hpp" #include "fs.hpp"
#include <assert.h>
Fs::Fs(RawDisk *disk) : disk(disk) { Fs::Fs(RawDisk *disk) : disk(disk) {
assert((disk->diskSize / IO_BLOCK_SIZE) > assert((disk->diskSize / IO_BLOCK_SIZE) >

View File

@ -2,13 +2,15 @@
class DatablockOperation { class DatablockOperation {
public: public:
DatablockOperation(int (*_skip)(DatablockOperation *, u_int64_t) = nullptr)
: skip(_skip) {}
char *buf; char *buf;
size_t count; size_t count;
size_t offset; size_t offset;
size_t bytes_completed; size_t bytes_completed;
Fs *fs; Fs *fs;
virtual int operation(u_int64_t block_num, bool *delete_block) = 0; virtual int operation(u_int64_t block_num, bool *delete_block) = 0;
int (*skip)(DatablockOperation *, u_int64_t) = nullptr; int (*skip)(DatablockOperation *, u_int64_t);
}; };
int default_skip_func(DatablockOperation *this_op, u_int64_t num_blocks) { int default_skip_func(DatablockOperation *this_op, u_int64_t num_blocks) {
@ -20,7 +22,8 @@ int default_skip_func(DatablockOperation *this_op, u_int64_t num_blocks) {
return 1; return 1;
} }
int pass_skip_func(DatablockOperation *this_op, u_int64_t num_blocks) { int truncate_skip_func(DatablockOperation *this_op, u_int64_t num_blocks) {
this_op->offset = 0;
return 1; return 1;
} }
@ -75,16 +78,19 @@ int Fs::sweep_datablocks(u_int64_t *block_num, int indirect_num,
int err; int err;
int result = -1; int result = -1;
u_int64_t indirect_block_size = 1; u_int64_t indirect_block_size;
for (int i = 1; i < indirect_num; ++i) u_int64_t direct_block_size = 1;
indirect_block_size *= IO_BLOCK_SIZE; for (int i = 0; i < indirect_num; ++i) {
indirect_block_size = direct_block_size;
direct_block_size *= IO_BLOCK_SIZE;
}
if ((*block_num) == 0) { if ((*block_num) == 0) {
if (allocate) { if (allocate) {
if ((err = datablock_manager->new_datablock(block_num)) < 0) if ((err = datablock_manager->new_datablock(block_num)) < 0)
return err; return err;
} else if (op->skip != nullptr) { } else if (op->skip != nullptr) {
return (*(op->skip))(op, indirect_block_size * IO_BLOCK_SIZE); return (*(op->skip))(op, direct_block_size);
} }
} }
@ -152,6 +158,7 @@ int Fs::sweep_datablocks(u_int64_t *block_num, int indirect_num,
class ReadDatablockOperation : public DatablockOperation { class ReadDatablockOperation : public DatablockOperation {
public: public:
ReadDatablockOperation() : DatablockOperation() {}
int operation(u_int64_t block_num, bool *delete_block) override { int operation(u_int64_t block_num, bool *delete_block) override {
char datablock_buf[IO_BLOCK_SIZE]; char datablock_buf[IO_BLOCK_SIZE];
int err; int err;
@ -182,6 +189,7 @@ public:
class WriteDatablockOperation : public DatablockOperation { class WriteDatablockOperation : public DatablockOperation {
public: public:
WriteDatablockOperation() : DatablockOperation() {}
int operation(u_int64_t block_num, bool *delete_block) override { int operation(u_int64_t block_num, bool *delete_block) override {
char datablock_buf[IO_BLOCK_SIZE]; char datablock_buf[IO_BLOCK_SIZE];
int err; int err;
@ -209,27 +217,39 @@ public:
class TruncateDatablockOperation : public DatablockOperation { class TruncateDatablockOperation : public DatablockOperation {
public: public:
TruncateDatablockOperation() : skip(pass_skip_func) {} TruncateDatablockOperation() : DatablockOperation(truncate_skip_func) {}
int operation(u_int64_t block_num, bool *delete_block) override { int operation(u_int64_t block_num, bool *delete_block) override {
if (offset != 0) char datablock_buf[IO_BLOCK_SIZE];
int err;
if (offset == 0) {
(*delete_block) = true;
return 1; return 1;
}
if ((err = fs->disk->read_block(block_num, datablock_buf)) < 0)
return err;
memset(&datablock_buf[offset], 0, IO_BLOCK_SIZE - offset);
if ((err = fs->disk->write_block(block_num, datablock_buf)) < 0)
return err;
offset = 0; offset = 0;
delete_block = true;
return 1; return 1;
} }
}; };
class LseekNextDataDatablockOperation : public DatablockOperation { class LseekNextDataDatablockOperation : public DatablockOperation {
public: public:
LseekNextDataDatablockOperation() : skip(default_skip_func) {} LseekNextDataDatablockOperation() : DatablockOperation(default_skip_func) {}
int operation(u_int64_t block_num, bool *delete_block) override { return 0; } int operation(u_int64_t block_num, bool *delete_block) override { return 0; }
}; };
class LseekNextHoleDatablockOperation : public DatablockOperation { class LseekNextHoleDatablockOperation : public DatablockOperation {
public: public:
LseekNextHoleDatablockOperation() : DatablockOperation() {}
int operation(u_int64_t block_num, bool *delete_block) override { int operation(u_int64_t block_num, bool *delete_block) override {
if (block_num == 0) if (block_num == 0)
return 0; return 0;
@ -307,7 +327,7 @@ int Fs::truncate(INode_Data *inode_data, size_t length) {
return 0; return 0;
} }
int Fs::lseek_next_data(INode_Data *inode_data, size_t offset) { ssize_t Fs::lseek_next_data(INode_Data *inode_data, size_t offset) {
int err; int err;
if (offset >= inode_data->metadata.size) if (offset >= inode_data->metadata.size)
@ -332,7 +352,7 @@ int Fs::lseek_next_data(INode_Data *inode_data, size_t offset) {
return op.bytes_completed; return op.bytes_completed;
} }
int Fs::lseek_next_hole(INode_Data *inode_data, size_t offset) { ssize_t Fs::lseek_next_hole(INode_Data *inode_data, size_t offset) {
int err; int err;
if (offset >= inode_data->metadata.size) if (offset >= inode_data->metadata.size)

View File

@ -1,74 +0,0 @@
#include "fs.hpp"
int Fs::deallocate_datablock(INode_Data *inode_data, u_int64_t *datablock_num) {
int result;
result = deallocate_indirect(&(inode_data->triple_indirect_block), 3,
datablock_num);
if (result <= 0)
return result;
result = deallocate_indirect(&(inode_data->double_indirect_block), 2,
datablock_num);
if (result <= 0)
return result;
result = deallocate_indirect(&(inode_data->single_indirect_block), 1,
datablock_num);
if (result <= 0)
return result;
for (size_t i = NUMBER_OF_DIRECT_BLOCKS - 1; i >= 0; --i) {
result =
deallocate_indirect(&(inode_data->direct_blocks[i]), 0, datablock_num);
if (result <= 0)
return result;
}
return -1;
}
int Fs::deallocate_indirect(u_int64_t *storage, int n,
u_int64_t *datablock_num) {
char buf[IO_BLOCK_SIZE];
int result;
if (*storage == 0)
return 1;
if (n == 0) {
u_int64_t temp_datablock_num = (*storage);
if ((result = datablock_manager->free_datablock(*storage)) < 0)
return result;
(*datablock_num) = temp_datablock_num;
(*storage) = 0;
return 0;
}
u_int64_t temp;
if ((result = disk->read_block(*storage, buf)) < 0)
return result;
for (size_t i = IO_BLOCK_SIZE - sizeof(u_int64_t); i >= 0;
i -= sizeof(u_int64_t)) {
read_u64(&temp, &buf[i]);
result = deallocate_indirect(&temp, n - 1, datablock_num);
if (result < 0)
return result;
if (result == 0) {
if (i == 0 && temp == 0) {
if ((result = datablock_manager->free_datablock(*storage)) < 0)
return result;
(*storage) = 0;
} else {
write_u64(temp, &buf[i]);
if ((result = disk->write_block(*storage, buf)) < 0)
return result;
}
return 0;
}
}
return 1;
}

View File

@ -34,10 +34,64 @@ int main() {
// disk->print_block(1597); // disk->print_block(1597);
// return 0;
int err; int err;
// RawDisk *disk = new FakeRawDisk(2048);
// Fs *fs = new Fs(disk);
// fs->format();
// disk->print_block(0);
// disk->print_block(1);
// INode_Data inode_data;
// fs->inode_manager->new_inode(1, 2, 3, &inode_data);
// disk->print_block(0);
// disk->print_block(1);
int BL_SIZE = 4096 / 8;
// u_int64_t buf[BL_SIZE * (56 + 512 + 10)];
// for (int i = 0; i < BL_SIZE * (56 + 512 + 10); ++i)
// buf[i] = (i / BL_SIZE) + 1;
// err = fs->write(&inode_data, (char *)buf, 4096 * (56 + 3) + 16 + 8, 0);
// fs->inode_manager->save_inode(&inode_data);
// printf("Write %d", err);
// disk->print_block(0);
// disk->print_block(1);
// disk->print_block(1025);
// disk->print_block(1026);
// disk->print_block(1027);
// disk->print_block(1080);
// disk->print_block(1081);
// disk->print_block(1082);
// disk->print_block(1083);
// disk->print_block(1084);
// disk->print_block(1085);
// int N = 5;
// u_int64_t buf2[4096] = {0};
// err = fs->read(&inode_data, (char *)buf2, (8 * N), 4096 - 8 - 8);
// printf("\n\nREAD: %d\n", err);
// for (int i = 0; i < N; ++i)
// printf("%d ", buf2[i]);
// printf("\n");
u_int64_t big_buf[BL_SIZE * 1000];
char *buf = (char *)big_buf;
int offs = 55 * 4096;
RawDisk *disk = new FakeRawDisk(2048); RawDisk *disk = new FakeRawDisk(2048);
Fs *fs = new Fs(disk); Fs *fs = new Fs(disk);
fs->format(); fs->format();
disk->print_block(0); disk->print_block(0);
disk->print_block(1); disk->print_block(1);
@ -47,40 +101,68 @@ int main() {
disk->print_block(0); disk->print_block(0);
disk->print_block(1); disk->print_block(1);
disk->print_block(1024);
int BL_SIZE = 4096 / 8; for (int i = 0; i < BL_SIZE * 3; ++i)
big_buf[i] = 1;
u_int64_t buf[BL_SIZE * (56 + 512 + 10)]; err = fs->write(&inode_data, buf, 4096 * 3, offs);
for (int i = 0; i < BL_SIZE * (56 + 512 + 10); ++i) for (int i = 0; i < BL_SIZE * 3; ++i)
buf[i] = (i / BL_SIZE) + 1; big_buf[i] = 2;
err = fs->truncate(&inode_data, offs + 4096);
err = fs->write(&inode_data, buf, 4096 * 2, offs + 4096 * 2);
err = fs->truncate(&inode_data, offs + 4096 * 2);
err = fs->write(&inode_data, (char *)buf, 4096 * (56 + 3) + 16 + 8, 0);
fs->inode_manager->save_inode(&inode_data); fs->inode_manager->save_inode(&inode_data);
printf("Write %d", err); printf("Write %d", err);
disk->print_block(0); disk->print_block(0);
disk->print_block(1); disk->print_block(1);
disk->print_block(1024);
disk->print_block(1025); disk->print_block(1025);
disk->print_block(1026); disk->print_block(1026);
disk->print_block(1027); disk->print_block(1027);
disk->print_block(1080); disk->print_block(1028);
disk->print_block(1081); disk->print_block(1029);
disk->print_block(1082); // disk->print_block(1080);
disk->print_block(1083); // disk->print_block(1081);
disk->print_block(1084); // disk->print_block(1082);
disk->print_block(1085); // disk->print_block(1083);
// disk->print_block(1084);
// disk->print_block(1085);
int N = 5; // err = fs->truncate(&inode_data, 4096 + 4);
// fs->inode_manager->save_inode(&inode_data);
// printf("Truncate %d", err);
u_int64_t buf2[4096] = {0}; // disk->print_block(0);
err = fs->read(&inode_data, (char *)buf2, (8 * N), 4096 - 8 - 8); // disk->print_block(1);
// disk->print_block(1024);
// disk->print_block(1025);
// disk->print_block(1026);
// disk->print_block(1027);
// disk->print_block(1028);
printf("\n\nREAD: %d\n", err); err = fs->lseek_next_hole(&inode_data, offs + 0);
for (int i = 0; i < N; ++i) printf("lseek_next_hole (%d): %d\n\n", offs + 0, err);
printf("%d ", buf2[i]); err = fs->lseek_next_hole(&inode_data, offs + 1);
printf("\n"); printf("lseek_next_hole (%d): %d\n\n", offs + 1, err);
err = fs->lseek_next_hole(&inode_data, offs + 4096);
printf("lseek_next_hole (%d): %d\n\n", offs + 4096, err);
err = fs->lseek_next_hole(&inode_data, offs + 4097);
printf("lseek_next_hole (%d): %d\n\n", offs + 4097, err);
err = fs->lseek_next_hole(&inode_data, offs + 8192);
printf("lseek_next_hole (%d): %d\n\n", offs + 8192, err);
err = fs->lseek_next_hole(&inode_data, offs + 8193);
printf("lseek_next_hole (%d): %d\n\n", offs + 8193, err);
err = fs->lseek_next_hole(&inode_data, offs + 12288);
printf("lseek_next_hole (%d): %d\n\n", offs + 12288, err);
err = fs->lseek_next_hole(&inode_data, offs + 12289);
printf("lseek_next_hole (%d): %d\n\n", offs + 12289, err);
err = fs->lseek_next_hole(&inode_data, offs + 100000);
printf("lseek_next_hole (%d): %d\n\n", offs + 100000, err);
return 0; return 0;
} }

View File

@ -10,12 +10,12 @@ void RawDisk::print_block(u_int64_t block_number) {
return; return;
} }
printf("\nBlock %llu:\n", block_number); printf("\nBlock %lu:\n", block_number);
for (int i = 0; i < IO_BLOCK_SIZE; i += sizeof(u_int64_t)) { for (int i = 0; i < IO_BLOCK_SIZE; i += sizeof(u_int64_t)) {
num = 0; num = 0;
for (int j = 0; j < 8; j++) for (int j = 0; j < 8; j++)
num |= ((u_int64_t)(unsigned char)buf[i + j]) << (8 * j); num |= ((u_int64_t)(unsigned char)buf[i + j]) << (8 * j);
printf("%llu ", num); printf("%lu ", num);
if ((i / sizeof(u_int64_t)) % nums_per_line == nums_per_line - 1) if ((i / sizeof(u_int64_t)) % nums_per_line == nums_per_line - 1)
printf("\n"); printf("\n");
} }
@ -47,8 +47,8 @@ RealRawDisk::RealRawDisk(const char *directory)
numSectors = diskSize / 512; // Assuming a sector size of 512 bytes numSectors = diskSize / 512; // Assuming a sector size of 512 bytes
printf("====Initializing RawDisk====\n"); printf("====Initializing RawDisk====\n");
printf("Number of sectors: %llu\n", numSectors); printf("Number of sectors: %lu\n", numSectors);
printf("Disk size (in bytes): %llu\n", diskSize); printf("Disk size (in bytes): %lu\n", diskSize);
} }
RealRawDisk::~RealRawDisk() { RealRawDisk::~RealRawDisk() {
@ -101,7 +101,7 @@ FakeRawDisk::FakeRawDisk(u_int64_t num_blocks) {
exit(1); exit(1);
} }
printf("====Initializing FAKE RawDisk====\n"); printf("====Initializing FAKE RawDisk====\n");
printf("FAKE Disk size (in bytes): %llu\n", diskSize); printf("FAKE Disk size (in bytes): %lu\n", diskSize);
perror("!!! USING FAKE RawDisk - THIS IS FOR TESTING ONLY !!!"); perror("!!! USING FAKE RawDisk - THIS IS FOR TESTING ONLY !!!");
} }

View File

@ -19,7 +19,7 @@ add_executable(${TARGET_LAYER1_API}
../lib/rawdisk.cpp ../lib/rawdisk.cpp
../lib/fs/datablock_manager.cpp ../lib/fs/datablock_manager.cpp
../lib/fs/fs_data_types.cpp ../lib/fs/fs_data_types.cpp
../lib/fs/fs_resize.cpp ../lib/fs/fs_file_io.cpp
../lib/fs/fs.cpp ../lib/fs/fs.cpp
../lib/fs/inode_manager.cpp ../lib/fs/inode_manager.cpp
) )

View File

@ -65,12 +65,12 @@ int main(int argc, char *argv[]) {
1); // the first 8 bytes of 4k I/O block will store 1); // the first 8 bytes of 4k I/O block will store
// the next address(after 2048*4k I/O block) // the next address(after 2048*4k I/O block)
// test the end of the datablock // test the end of the datablock
H->read_block(NUM_BLOCKS - DATABLOCKS_PER_BITMAP_BLOCK - 1, buffer); // H->read_block(NUM_BLOCKS - DATABLOCKS_PER_BITMAP_BLOCK - 1, buffer);
t = 0; // t = 0;
for (int j = 0; j < 8; j++) // for (int j = 0; j < 8; j++)
t |= ((u_int64_t)(unsigned char)buffer[j]) << (8 * j); // t |= ((u_int64_t)(unsigned char)buffer[j]) << (8 * j);
assert(t == NUM_BLOCKS - DATABLOCKS_PER_BITMAP_BLOCK - 1); // assert(t == NUM_BLOCKS - DATABLOCKS_PER_BITMAP_BLOCK - 1);
/***************************test inode /***************************test inode
* de/allocation**********************************/ * de/allocation**********************************/
@ -108,34 +108,35 @@ int main(int argc, char *argv[]) {
// after free the datablock, the program will find the first smallest address // after free the datablock, the program will find the first smallest address
// of datablock to give to the inode should test random resize each node, but // of datablock to give to the inode should test random resize each node, but
// should use datablock_free data structure to record // should use datablock_free data structure to record
u_int64_t rec_datablock_free[10][3] = {0}; // array version // u_int64_t rec_datablock_free[10][3] = {0}; // array version
u_int64_t temp_block_num = 0; // u_int64_t temp_block_num = 0;
for (int i = 0; i < 10; i++) { // for (int i = 0; i < 10; i++) {
// printf("%dth data block starting addres: ", i); // // printf("%dth data block starting addres: ", i);
for (int j = 0; j < 6; j++) { // for (int j = 0; j < 6; j++) {
fs->allocate_datablock(&inode_list[i], &temp_block_num); // fs->allocate_datablock(&inode_list[i], &temp_block_num);
// printf("%d," ,inode_inside[i].datablock_allocate(*H)); // // printf("%d," ,inode_inside[i].datablock_allocate(*H));
} // }
// printf("\n"); // // printf("\n");
} // }
for (int i = 0; i < 10; i++) { // for (int i = 0; i < 10; i++) {
// printf("%dth data block free addres: ", i); // // printf("%dth data block free addres: ", i);
for (int j = 2; j >= 0; j--) { // for (int j = 2; j >= 0; j--) {
fs->deallocate_datablock(&inode_list[i], &(rec_datablock_free[i][j])); // fs->deallocate_datablock(&inode_list[i],
// printf("", rec_datablock_free[i][j]); // &(rec_datablock_free[i][j]));
} // // printf("", rec_datablock_free[i][j]);
// printf("\n"); // }
} // // printf("\n");
// }
for (int i = 0; i < 10; i++) { // for (int i = 0; i < 10; i++) {
// printf("%dth data block allocate again addres: ", i); // // printf("%dth data block allocate again addres: ", i);
for (int j = 0; j < 3; j++) { // for (int j = 0; j < 3; j++) {
fs->allocate_datablock(&inode_list[i], &temp_block_num); // fs->allocate_datablock(&inode_list[i], &temp_block_num);
assert(temp_block_num == rec_datablock_free[i][j]); // assert(temp_block_num == rec_datablock_free[i][j]);
// printf("%d," ,inode_inside[i].datablock_allocate(*H)); // // printf("%d," ,inode_inside[i].datablock_allocate(*H));
} // }
// printf("\n"); // // printf("\n");
} // }
// printf("}\n"); // printf("}\n");
delete H; // Delete the RawDisk object delete H; // Delete the RawDisk object