fixed fileio bug
This commit is contained in:
parent
4dcb74d29e
commit
f3a9022897
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
229
lib/main.cpp
229
lib/main.cpp
@ -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;
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user