fixed fileio bug

This commit is contained in:
Connor 2023-12-01 20:39:12 -08:00
parent 4dcb74d29e
commit f3a9022897
3 changed files with 587 additions and 439 deletions

View File

@ -16,7 +16,7 @@ public:
~Fs(); ~Fs();
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, const char buf[], size_t count,
size_t offset); size_t offset);
int truncate(INode_Data *inode_data, size_t length); int truncate(INode_Data *inode_data, size_t length);
ssize_t lseek_next_data(INode_Data *inode_data, size_t offset); ssize_t lseek_next_data(INode_Data *inode_data, size_t offset);

View File

@ -1,378 +1,419 @@
#include "fs.hpp" #include "fs.hpp"
class DatablockOperation { const u_int64_t INDIRECT_BLOCKS = IO_BLOCK_SIZE / sizeof(u_int64_t);
public:
DatablockOperation(int (*_skip)(DatablockOperation *, u_int64_t) = nullptr) class DatablockOperation {
: skip(_skip) {} public:
char *buf; DatablockOperation(int (*_skip)(DatablockOperation *, u_int64_t) = nullptr)
size_t count; : skip(_skip) {}
size_t offset; size_t count;
size_t bytes_completed; size_t offset;
Fs *fs; size_t bytes_completed;
virtual int operation(u_int64_t block_num, bool *delete_block) = 0; Fs *fs;
int (*skip)(DatablockOperation *, u_int64_t); virtual int operation(u_int64_t block_num, bool *delete_block) = 0;
}; int (*skip)(DatablockOperation *, u_int64_t);
};
int default_skip_func(DatablockOperation *this_op, u_int64_t num_blocks) {
this_op->bytes_completed += (num_blocks * IO_BLOCK_SIZE) - this_op->offset; int default_skip_func(DatablockOperation *this_op, u_int64_t num_blocks) {
this_op->offset = 0; this_op->bytes_completed += (num_blocks * IO_BLOCK_SIZE) - this_op->offset;
this_op->offset = 0;
if (this_op->bytes_completed >= this_op->count)
return 0; if (this_op->bytes_completed >= this_op->count)
return 1; return 0;
} return 1;
}
int truncate_skip_func(DatablockOperation *this_op, u_int64_t num_blocks) {
this_op->offset = 0; int truncate_skip_func(DatablockOperation *this_op, u_int64_t num_blocks) {
return 1; this_op->offset = 0;
} return 1;
}
int Fs::sweep_inode_datablocks(INode_Data *inode_data,
u_int64_t start_block_index, bool allocate, int Fs::sweep_inode_datablocks(INode_Data *inode_data,
DatablockOperation *op) { u_int64_t start_block_index, bool allocate,
int result; DatablockOperation *op) {
int result;
u_int64_t start_index = start_block_index;
for (size_t i = start_index; i < NUMBER_OF_DIRECT_BLOCKS; ++i) { // printf("test2.1\n");
if ((result = sweep_datablocks(&(inode_data->direct_blocks[i]), 0, 0,
allocate, op)) <= 0) u_int64_t start_index = start_block_index;
return result; for (size_t i = start_index; i < NUMBER_OF_DIRECT_BLOCKS; ++i) {
start_index = NUMBER_OF_DIRECT_BLOCKS; if ((result = sweep_datablocks(&(inode_data->direct_blocks[i]), 0, 0,
} allocate, op)) <= 0)
return result;
start_index -= NUMBER_OF_DIRECT_BLOCKS; start_index = NUMBER_OF_DIRECT_BLOCKS;
}
if (start_index < IO_BLOCK_SIZE) {
if ((result = sweep_datablocks(&(inode_data->single_indirect_block), 1, // printf("test2.2\n");
start_index, allocate, op)) <= 0)
return result; start_index -= NUMBER_OF_DIRECT_BLOCKS;
start_index = IO_BLOCK_SIZE;
} if (start_index < INDIRECT_BLOCKS) {
if ((result = sweep_datablocks(&(inode_data->single_indirect_block), 1,
start_index -= IO_BLOCK_SIZE; start_index, allocate, op)) <= 0)
return result;
if (start_index < IO_BLOCK_SIZE * IO_BLOCK_SIZE) { start_index = INDIRECT_BLOCKS;
if ((result = sweep_datablocks(&(inode_data->double_indirect_block), 2, }
start_index, allocate, op)) <= 0)
return result; // printf("test2.3\n");
start_index = IO_BLOCK_SIZE * IO_BLOCK_SIZE;
} start_index -= INDIRECT_BLOCKS;
start_index -= IO_BLOCK_SIZE * IO_BLOCK_SIZE; if (start_index < INDIRECT_BLOCKS * INDIRECT_BLOCKS) {
if ((result = sweep_datablocks(&(inode_data->double_indirect_block), 2,
if (start_index < (u_int64_t)IO_BLOCK_SIZE * IO_BLOCK_SIZE * IO_BLOCK_SIZE) { start_index, allocate, op)) <= 0)
if ((result = sweep_datablocks(&(inode_data->triple_indirect_block), 3, return result;
start_index, allocate, op)) <= 0) start_index = INDIRECT_BLOCKS * INDIRECT_BLOCKS;
return result; }
}
// printf("test2.4\n");
return 1;
} start_index -= INDIRECT_BLOCKS * INDIRECT_BLOCKS;
// This can simply be made non recursive by copy pasting - it is just if (start_index <
// written this way as a proof of concept (u_int64_t)INDIRECT_BLOCKS * INDIRECT_BLOCKS * INDIRECT_BLOCKS) {
int Fs::sweep_datablocks(u_int64_t *block_num, int indirect_num, if ((result = sweep_datablocks(&(inode_data->triple_indirect_block), 3,
u_int64_t start_block_index, bool allocate, start_index, allocate, op)) <= 0)
DatablockOperation *op) { return result;
char buf[IO_BLOCK_SIZE]; }
int err;
int result = -1; return 1;
}
u_int64_t indirect_block_size;
u_int64_t direct_block_size = 1; // This can simply be made non recursive by copy pasting - it is just
for (int i = 0; i < indirect_num; ++i) { // written this way as a proof of concept
indirect_block_size = direct_block_size; int Fs::sweep_datablocks(u_int64_t *block_num, int indirect_num,
direct_block_size *= IO_BLOCK_SIZE; u_int64_t start_block_index, bool allocate,
} DatablockOperation *op) {
char buf[IO_BLOCK_SIZE];
if ((*block_num) == 0) { int err;
if (allocate) { int result = -1;
if ((err = datablock_manager->new_datablock(block_num)) < 0)
return err; u_int64_t num_blocks_indirect;
} else if (op->skip != nullptr) { u_int64_t num_blocks = 1;
return (*(op->skip))(op, direct_block_size); for (int i = 0; i < indirect_num; ++i) {
} num_blocks_indirect = num_blocks;
} num_blocks *= INDIRECT_BLOCKS;
}
if (indirect_num == 0) {
bool delete_block = false; // printf("test2.3.1 %d\n", indirect_num);
if ((result = op->operation(*block_num, &delete_block)) < 0)
return result; if ((*block_num) == 0) {
if (delete_block) { if (allocate) {
if ((err = datablock_manager->free_datablock(*block_num)) < 0) if ((err = datablock_manager->new_datablock(block_num)) < 0)
return err; return err;
(*block_num) = 0; } else if (op->skip != nullptr) {
} return (*(op->skip))(op, num_blocks);
return result; }
} }
if ((*block_num) == 0) { // printf("test2.3.2 %d\n", indirect_num);
memset(buf, 0, sizeof(buf));
} else { if (indirect_num == 0) {
if ((err = disk->read_block(*block_num, buf)) < 0) bool delete_block = false;
return err; if ((result = op->operation(*block_num, &delete_block)) < 0)
} return result;
if (delete_block) {
u_int64_t this_layer_start_index = start_block_index / indirect_block_size; if ((err = datablock_manager->free_datablock(*block_num)) < 0)
u_int64_t next_layer_start_index = return err;
start_block_index - (indirect_block_size * this_layer_start_index); (*block_num) = 0;
}
u_int64_t temp; return result;
u_int64_t next_block_num; }
bool modified = false;
// printf("test2.3.3 %d\n", indirect_num);
for (size_t i = this_layer_start_index * sizeof(u_int64_t); i < IO_BLOCK_SIZE;
i += sizeof(u_int64_t)) { if ((*block_num) == 0) {
read_u64(&temp, &buf[i]); memset(buf, 0, sizeof(buf));
next_block_num = temp; } else {
if ((result = sweep_datablocks(&next_block_num, indirect_num - 1, if ((err = disk->read_block(*block_num, buf)) < 0)
next_layer_start_index, allocate, op)) < 0) return err;
return result; }
if (next_block_num != temp) {
write_u64(next_block_num, &buf[i]); // printf("test2.3.4 %d\n", indirect_num);
modified = true;
} u_int64_t this_layer_start_index = start_block_index / num_blocks_indirect;
if (result == 0) u_int64_t next_layer_start_index =
break; start_block_index - (num_blocks_indirect * this_layer_start_index);
}
u_int64_t temp;
if (modified) { u_int64_t next_block_num;
bool delete_block = true; bool modified = false;
for (size_t i = 0; i < IO_BLOCK_SIZE; ++i)
if (buf[i] != 0) { // printf("test2.3.4- %d\n", indirect_num);
delete_block = false;
break; // printf("start_block_index=%d\n", start_block_index);
} // printf("this_layer_start_index=%d\n", this_layer_start_index);
if (delete_block) { // printf("next_layer_start_index=%d\n", next_layer_start_index);
if ((err = datablock_manager->free_datablock(*block_num)) < 0) // printf("num_blocks_indirect=%d\n", num_blocks_indirect);
return err;
(*block_num) = 0; for (size_t i = this_layer_start_index * sizeof(u_int64_t); i < IO_BLOCK_SIZE;
} else { i += sizeof(u_int64_t)) {
if ((err = disk->write_block(*block_num, buf)) < 0) // printf("test2.3.5- %d\n", indirect_num);
return err; read_u64(&temp, &buf[i]);
} next_block_num = temp;
} if ((result = sweep_datablocks(&next_block_num, indirect_num - 1,
next_layer_start_index, allocate, op)) < 0)
return result; return result;
} if (next_block_num != temp) {
write_u64(next_block_num, &buf[i]);
class ReadDatablockOperation : public DatablockOperation { modified = true;
public: }
ReadDatablockOperation() : DatablockOperation() {} if (result == 0)
int operation(u_int64_t block_num, bool *delete_block) override { break;
char datablock_buf[IO_BLOCK_SIZE]; }
int err;
// printf("test2.3.6 %d\n", indirect_num);
// printf("PRINT: (%d) %d %d %d\n", block_num, count, offset,
// bytes_completed); if (modified) {
bool delete_block = true;
size_t read_size = for (size_t i = 0; i < IO_BLOCK_SIZE; ++i)
std::min(IO_BLOCK_SIZE - offset, count - bytes_completed); if (buf[i] != 0) {
delete_block = false;
if (block_num != 0) { break;
if ((err = fs->disk->read_block(block_num, datablock_buf)) < 0) }
return err; if (delete_block) {
if ((err = datablock_manager->free_datablock(*block_num)) < 0)
memcpy(&buf[bytes_completed], &datablock_buf[offset], read_size); return err;
} else { (*block_num) = 0;
memset(&buf[bytes_completed], 0, read_size); } else {
} if ((err = disk->write_block(*block_num, buf)) < 0)
return err;
offset = 0; }
bytes_completed += read_size; }
if (bytes_completed >= count) // printf("test2.3.7 %d\n", indirect_num);
return 0; // printf("test2.3.8 result=%d %d\n", result, indirect_num);
return 1;
} return result;
}; }
class WriteDatablockOperation : public DatablockOperation { class ReadDatablockOperation : public DatablockOperation {
public: public:
WriteDatablockOperation() : DatablockOperation() {} char *buf;
int operation(u_int64_t block_num, bool *delete_block) override { ReadDatablockOperation() : DatablockOperation() {}
char datablock_buf[IO_BLOCK_SIZE]; int operation(u_int64_t block_num, bool *delete_block) override {
int err; char datablock_buf[IO_BLOCK_SIZE];
int err;
size_t write_size =
std::min(IO_BLOCK_SIZE - offset, count - bytes_completed); // printf("PRINT: (%d) %d %d %d\n", block_num, count, offset,
// bytes_completed);
if (write_size < IO_BLOCK_SIZE)
if ((err = fs->disk->read_block(block_num, datablock_buf)) < 0) size_t read_size =
return err; std::min(IO_BLOCK_SIZE - offset, count - bytes_completed);
memcpy(&datablock_buf[offset], &buf[bytes_completed], write_size); if (block_num != 0) {
if ((err = fs->disk->read_block(block_num, datablock_buf)) < 0)
if ((err = fs->disk->write_block(block_num, datablock_buf)) < 0) return err;
return err;
memcpy(&buf[bytes_completed], &datablock_buf[offset], read_size);
offset = 0; } else {
bytes_completed += write_size; memset(&buf[bytes_completed], 0, read_size);
}
if (bytes_completed >= count)
return 0; offset = 0;
return 1; bytes_completed += read_size;
}
}; if (bytes_completed >= count)
return 0;
class TruncateDatablockOperation : public DatablockOperation { return 1;
public: }
TruncateDatablockOperation() : DatablockOperation(truncate_skip_func) {} };
int operation(u_int64_t block_num, bool *delete_block) override {
char datablock_buf[IO_BLOCK_SIZE]; class WriteDatablockOperation : public DatablockOperation {
int err; public:
const char *buf;
if (offset == 0) { WriteDatablockOperation() : DatablockOperation() {}
(*delete_block) = true; int operation(u_int64_t block_num, bool *delete_block) override {
return 1; char datablock_buf[IO_BLOCK_SIZE];
} int err;
if ((err = fs->disk->read_block(block_num, datablock_buf)) < 0) // printf("w: %d\n", bytes_completed);
return err;
size_t write_size =
memset(&datablock_buf[offset], 0, IO_BLOCK_SIZE - offset); std::min(IO_BLOCK_SIZE - offset, count - bytes_completed);
if ((err = fs->disk->write_block(block_num, datablock_buf)) < 0) if (write_size < IO_BLOCK_SIZE)
return err; if ((err = fs->disk->read_block(block_num, datablock_buf)) < 0)
return err;
offset = 0;
memcpy(&datablock_buf[offset], &buf[bytes_completed], write_size);
return 1;
} if ((err = fs->disk->write_block(block_num, datablock_buf)) < 0)
}; return err;
class LseekNextDataDatablockOperation : public DatablockOperation { offset = 0;
public: bytes_completed += write_size;
LseekNextDataDatablockOperation() : DatablockOperation(default_skip_func) {}
int operation(u_int64_t block_num, bool *delete_block) override { return 0; } if (bytes_completed >= count)
}; return 0;
return 1;
class LseekNextHoleDatablockOperation : public DatablockOperation { }
public: };
LseekNextHoleDatablockOperation() : DatablockOperation() {}
int operation(u_int64_t block_num, bool *delete_block) override { class TruncateDatablockOperation : public DatablockOperation {
if (block_num == 0) public:
return 0; TruncateDatablockOperation() : DatablockOperation(truncate_skip_func) {}
int operation(u_int64_t block_num, bool *delete_block) override {
bytes_completed += (IO_BLOCK_SIZE)-offset; char datablock_buf[IO_BLOCK_SIZE];
offset = 0; int err;
if (bytes_completed >= count) if (offset == 0) {
return 0; (*delete_block) = true;
return 1; return 1;
} }
};
if ((err = fs->disk->read_block(block_num, datablock_buf)) < 0)
ssize_t Fs::read(INode_Data *inode_data, char buf[], size_t count, return err;
size_t offset) {
int err; memset(&datablock_buf[offset], 0, IO_BLOCK_SIZE - offset);
u_int64_t start_block_index = offset / IO_BLOCK_SIZE; if ((err = fs->disk->write_block(block_num, datablock_buf)) < 0)
size_t internal_offset = offset - (start_block_index * IO_BLOCK_SIZE); return err;
ReadDatablockOperation op = ReadDatablockOperation(); offset = 0;
op.offset = internal_offset;
op.buf = buf; return 1;
op.count = std::min(count, inode_data->metadata.size - offset); }
op.bytes_completed = 0; };
op.fs = this;
class LseekNextDataDatablockOperation : public DatablockOperation {
if ((err = sweep_inode_datablocks(inode_data, start_block_index, false, public:
&op)) != 0) LseekNextDataDatablockOperation() : DatablockOperation(default_skip_func) {}
return err; int operation(u_int64_t block_num, bool *delete_block) override { return 0; }
};
return op.bytes_completed;
} class LseekNextHoleDatablockOperation : public DatablockOperation {
public:
ssize_t Fs::write(INode_Data *inode_data, char buf[], size_t count, LseekNextHoleDatablockOperation() : DatablockOperation() {}
size_t offset) { int operation(u_int64_t block_num, bool *delete_block) override {
int err; if (block_num == 0)
return 0;
u_int64_t start_block_index = offset / IO_BLOCK_SIZE;
size_t internal_offset = offset - (start_block_index * IO_BLOCK_SIZE); bytes_completed += (IO_BLOCK_SIZE)-offset;
offset = 0;
WriteDatablockOperation op = WriteDatablockOperation();
op.offset = internal_offset; if (bytes_completed >= count)
op.buf = buf; return 0;
op.count = count; return 1;
op.bytes_completed = 0; }
op.fs = this; };
if ((err = sweep_inode_datablocks(inode_data, start_block_index, true, ssize_t Fs::read(INode_Data *inode_data, char buf[], size_t count,
&op)) != 0) size_t offset) {
return err; int err;
inode_data->metadata.size = u_int64_t start_block_index = offset / IO_BLOCK_SIZE;
std::max(offset + op.bytes_completed, inode_data->metadata.size); size_t internal_offset = offset - (start_block_index * IO_BLOCK_SIZE);
return op.bytes_completed; ReadDatablockOperation op = ReadDatablockOperation();
} op.offset = internal_offset;
op.buf = buf;
int Fs::truncate(INode_Data *inode_data, size_t length) { op.count = std::min(count, inode_data->metadata.size - offset);
int err; op.bytes_completed = 0;
op.fs = this;
u_int64_t start_block_index = length / IO_BLOCK_SIZE;
size_t internal_offset = length - (start_block_index * IO_BLOCK_SIZE); if ((err = sweep_inode_datablocks(inode_data, start_block_index, false,
&op)) != 0)
TruncateDatablockOperation op = TruncateDatablockOperation(); return err;
op.offset = internal_offset;
op.fs = this; return op.bytes_completed;
}
if ((err = sweep_inode_datablocks(inode_data, start_block_index, false,
&op)) < 0) ssize_t Fs::write(INode_Data *inode_data, const char buf[], size_t count,
return err; size_t offset) {
int err;
inode_data->metadata.size = length;
// printf("test1\n");
return 0;
} u_int64_t start_block_index = offset / IO_BLOCK_SIZE;
size_t internal_offset = offset - (start_block_index * IO_BLOCK_SIZE);
ssize_t Fs::lseek_next_data(INode_Data *inode_data, size_t offset) {
int err; WriteDatablockOperation op = WriteDatablockOperation();
op.offset = internal_offset;
if (offset >= inode_data->metadata.size) op.buf = buf;
return -1; op.count = count;
op.bytes_completed = 0;
u_int64_t start_block_index = offset / IO_BLOCK_SIZE; op.fs = this;
size_t internal_offset = offset - (start_block_index * IO_BLOCK_SIZE);
// printf("test2\n");
LseekNextDataDatablockOperation op = LseekNextDataDatablockOperation();
op.offset = internal_offset; if ((err = sweep_inode_datablocks(inode_data, start_block_index, true,
op.count = inode_data->metadata.size; &op)) != 0)
op.bytes_completed = offset; return err;
op.fs = this;
// printf("test3\n");
if ((err = sweep_inode_datablocks(inode_data, start_block_index, false,
&op)) < 0) inode_data->metadata.size =
return err; std::max(offset + op.bytes_completed, inode_data->metadata.size);
if (op.bytes_completed >= inode_data->metadata.size) return op.bytes_completed;
return -1; }
return op.bytes_completed; int Fs::truncate(INode_Data *inode_data, size_t length) {
} int err;
ssize_t Fs::lseek_next_hole(INode_Data *inode_data, size_t offset) { u_int64_t start_block_index = length / IO_BLOCK_SIZE;
int err; size_t internal_offset = length - (start_block_index * IO_BLOCK_SIZE);
if (offset >= inode_data->metadata.size) TruncateDatablockOperation op = TruncateDatablockOperation();
return -1; op.offset = internal_offset;
op.fs = this;
u_int64_t start_block_index = offset / IO_BLOCK_SIZE;
size_t internal_offset = offset - (start_block_index * IO_BLOCK_SIZE); if ((err = sweep_inode_datablocks(inode_data, start_block_index, false,
&op)) < 0)
LseekNextHoleDatablockOperation op = LseekNextHoleDatablockOperation(); return err;
op.offset = internal_offset;
op.count = inode_data->metadata.size; inode_data->metadata.size = length;
op.bytes_completed = offset;
op.fs = this; return 0;
}
if ((err = sweep_inode_datablocks(inode_data, start_block_index, false,
&op)) < 0) ssize_t Fs::lseek_next_data(INode_Data *inode_data, size_t offset) {
return err; int err;
if (op.bytes_completed >= inode_data->metadata.size) if (offset >= inode_data->metadata.size)
return inode_data->metadata.size; return -1;
return op.bytes_completed; u_int64_t start_block_index = offset / IO_BLOCK_SIZE;
size_t internal_offset = offset - (start_block_index * IO_BLOCK_SIZE);
LseekNextDataDatablockOperation op = LseekNextDataDatablockOperation();
op.offset = internal_offset;
op.count = inode_data->metadata.size;
op.bytes_completed = offset;
op.fs = this;
if ((err = sweep_inode_datablocks(inode_data, start_block_index, false,
&op)) < 0)
return err;
if (op.bytes_completed >= inode_data->metadata.size)
return -1;
return op.bytes_completed;
}
ssize_t Fs::lseek_next_hole(INode_Data *inode_data, size_t offset) {
int err;
if (offset >= inode_data->metadata.size)
return -1;
u_int64_t start_block_index = offset / IO_BLOCK_SIZE;
size_t internal_offset = offset - (start_block_index * IO_BLOCK_SIZE);
LseekNextHoleDatablockOperation op = LseekNextHoleDatablockOperation();
op.offset = internal_offset;
op.count = inode_data->metadata.size;
op.bytes_completed = offset;
op.fs = this;
if ((err = sweep_inode_datablocks(inode_data, start_block_index, false,
&op)) < 0)
return err;
if (op.bytes_completed >= inode_data->metadata.size)
return inode_data->metadata.size;
return op.bytes_completed;
} }

View File

@ -1,6 +1,12 @@
#define _GNU_SOURCE
#include "fischl.h" #include "fischl.h"
#include "fs.hpp" #include "fs.hpp"
#include <assert.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h>
int main() { int main() {
// printf("hello word!"); // printf("hello word!");
@ -36,7 +42,7 @@ int main() {
// return 0; // return 0;
int err; // int err;
// RawDisk *disk = new FakeRawDisk(2048); // RawDisk *disk = new FakeRawDisk(2048);
// Fs *fs = new Fs(disk); // Fs *fs = new Fs(disk);
@ -50,7 +56,7 @@ int main() {
// disk->print_block(0); // disk->print_block(0);
// disk->print_block(1); // disk->print_block(1);
int BL_SIZE = 4096 / 8; // int BL_SIZE = 4096 / 8;
// u_int64_t buf[BL_SIZE * (56 + 512 + 10)]; // u_int64_t buf[BL_SIZE * (56 + 512 + 10)];
@ -84,58 +90,39 @@ int main() {
// printf("%d ", buf2[i]); // printf("%d ", buf2[i]);
// printf("\n"); // printf("\n");
u_int64_t big_buf[BL_SIZE * 1000]; // u_int64_t big_buf[BL_SIZE * 1000];
char *buf = (char *)big_buf; // char *buf = (char *)big_buf;
int offs = 55 * 4096; // 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);
INode_Data inode_data; // INode_Data inode_data;
fs->inode_manager->new_inode(1, 2, 3, &inode_data); // fs->inode_manager->new_inode(1, 2, 3, &inode_data);
disk->print_block(0); // disk->print_block(0);
disk->print_block(1); // disk->print_block(1);
disk->print_block(1024); // disk->print_block(1024);
for (int i = 0; i < BL_SIZE * 3; ++i) // for (int i = 0; i < BL_SIZE * 3; ++i)
big_buf[i] = 1; // big_buf[i] = 1;
err = fs->write(&inode_data, buf, 4096 * 3, offs); // err = fs->write(&inode_data, buf, 4096 * 3, offs);
for (int i = 0; i < BL_SIZE * 3; ++i) // for (int i = 0; i < BL_SIZE * 3; ++i)
big_buf[i] = 2; // big_buf[i] = 2;
err = fs->truncate(&inode_data, offs + 4096); // err = fs->truncate(&inode_data, offs + 4096);
err = fs->write(&inode_data, buf, 4096 * 2, offs + 4096 * 2); // err = fs->write(&inode_data, buf, 4096 * 2, offs + 4096 * 2);
err = fs->truncate(&inode_data, offs + 4096 * 2); // err = fs->truncate(&inode_data, offs + 4096 * 2);
fs->inode_manager->save_inode(&inode_data);
printf("Write %d", err);
disk->print_block(0);
disk->print_block(1);
disk->print_block(1024);
disk->print_block(1025);
disk->print_block(1026);
disk->print_block(1027);
disk->print_block(1028);
disk->print_block(1029);
// disk->print_block(1080);
// disk->print_block(1081);
// disk->print_block(1082);
// disk->print_block(1083);
// disk->print_block(1084);
// disk->print_block(1085);
// err = fs->truncate(&inode_data, 4096 + 4);
// fs->inode_manager->save_inode(&inode_data); // fs->inode_manager->save_inode(&inode_data);
// printf("Truncate %d", err); // printf("Write %d", err);
// disk->print_block(0); // disk->print_block(0);
// disk->print_block(1); // disk->print_block(1);
@ -144,25 +131,145 @@ int main() {
// disk->print_block(1026); // disk->print_block(1026);
// disk->print_block(1027); // disk->print_block(1027);
// disk->print_block(1028); // disk->print_block(1028);
// disk->print_block(1029);
// // disk->print_block(1080);
// // disk->print_block(1081);
// // disk->print_block(1082);
// // disk->print_block(1083);
// // disk->print_block(1084);
// // disk->print_block(1085);
err = fs->lseek_next_hole(&inode_data, offs + 0); // // err = fs->truncate(&inode_data, 4096 + 4);
printf("lseek_next_hole (%d): %d\n\n", offs + 0, err); // // fs->inode_manager->save_inode(&inode_data);
err = fs->lseek_next_hole(&inode_data, offs + 1); // // printf("Truncate %d", err);
printf("lseek_next_hole (%d): %d\n\n", offs + 1, err);
err = fs->lseek_next_hole(&inode_data, offs + 4096); // // disk->print_block(0);
printf("lseek_next_hole (%d): %d\n\n", offs + 4096, err); // // disk->print_block(1);
err = fs->lseek_next_hole(&inode_data, offs + 4097); // // disk->print_block(1024);
printf("lseek_next_hole (%d): %d\n\n", offs + 4097, err); // // disk->print_block(1025);
err = fs->lseek_next_hole(&inode_data, offs + 8192); // // disk->print_block(1026);
printf("lseek_next_hole (%d): %d\n\n", offs + 8192, err); // // disk->print_block(1027);
err = fs->lseek_next_hole(&inode_data, offs + 8193); // // disk->print_block(1028);
printf("lseek_next_hole (%d): %d\n\n", offs + 8193, err);
err = fs->lseek_next_hole(&inode_data, offs + 12288); // err = fs->lseek_next_hole(&inode_data, offs + 0);
printf("lseek_next_hole (%d): %d\n\n", offs + 12288, err); // printf("lseek_next_hole (%d): %d\n\n", offs + 0, err);
err = fs->lseek_next_hole(&inode_data, offs + 12289); // err = fs->lseek_next_hole(&inode_data, offs + 1);
printf("lseek_next_hole (%d): %d\n\n", offs + 12289, err); // printf("lseek_next_hole (%d): %d\n\n", offs + 1, err);
err = fs->lseek_next_hole(&inode_data, offs + 100000); // err = fs->lseek_next_hole(&inode_data, offs + 4096);
printf("lseek_next_hole (%d): %d\n\n", offs + 100000, err); // 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);
// RawDisk *disk = new FakeRawDisk(2048);
// Fs *fs = new Fs(disk);
// fs->format();
// INode_Data inode_data;
// fs->inode_manager->new_inode(1, 2, 3, &inode_data);
// char cwd_buf[PATH_MAX];
// int fd;
// assert(getcwd(cwd_buf, sizeof(cwd_buf)) != NULL);
// printf("\n\n(");
// printf(cwd_buf);
// printf(")\n\n");
// fd = open("/home/connor", O_TMPFILE | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR);
// assert(fd != -1);
// u_int64_t test_start_range = IO_BLOCK_SIZE * 100;
// u_int64_t test_write_range = IO_BLOCK_SIZE * 50;
// u_int64_t test_read_range = IO_BLOCK_SIZE * 50;
// char zeros[test_write_range] = {0};
// char ones[test_write_range];
// memset(ones, 1, test_write_range);
// char *write_buf = ones;
// char reference_read_buf[test_read_range];
// char test_read_buf[test_read_range];
// size_t offset, count;
// int test_res, ref_res;
// for (int i = 0; i < 1000; ++i) {
// offset = rand() & test_start_range;
// switch (rand() % 2) {
// case 0:
// count = rand() & test_write_range;
// write_buf = (write_buf == ones) ? zeros : ones;
// 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_read_range;
// 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);
// bool reads_are_equal = true;
// for (size_t j = 0; j < count; ++j)
// if (test_read_buf[i] != reference_read_buf[i]) {
// reads_are_equal = false;
// break;
// }
// assert(reads_are_equal);
// break;
// }
// assert(test_res == ref_res);
// }
RawDisk *disk = new FakeRawDisk(5120);
Fs *fs = new Fs(disk);
fs->format();
int buf_size = IO_BLOCK_SIZE * 200;
int loops = 14 * 1024 * 1024 / buf_size;
char buf[buf_size];
memset(buf, 1, sizeof(buf));
INode_Data inode_data;
fs->inode_manager->new_inode(1, 2, 3, &inode_data);
int res;
for (int j = 0; j < loops; ++j) {
res = fs->write(&inode_data, buf, sizeof(buf), sizeof(buf) * j);
printf("write: %d j=%d\n", res, j);
}
for (int j = 0; j < loops; ++j) {
memset(buf, 0, sizeof(buf));
res = fs->read(&inode_data, buf, sizeof(buf), sizeof(buf) * j);
printf("read: %d j=%d\n", res, j);
for (int i = 0; i < sizeof(buf); ++i)
if (buf[1] != 1) {
printf("error: %d\n", i);
return -1;
}
}
return 0; return 0;
} }