changed manager file nemes

This commit is contained in:
Connor 2023-11-15 23:14:06 -08:00
parent 634180c3ce
commit 49c1643ab9
3 changed files with 269 additions and 269 deletions

View File

@ -13,11 +13,11 @@ add_executable(fischl
lib/fischl.cpp
lib/main.cpp
lib/rawdisk.cpp
lib/fs/datablock_allocator.cpp
lib/fs/datablock_manager.cpp
lib/fs/fs_data_types.cpp
lib/fs/fs_resize.cpp
lib/fs/fs.cpp
lib/fs/inode_allocator.cpp
lib/fs/inode_manager.cpp
)

View File

@ -1,136 +1,136 @@
#include "fs.hpp"
DataBlock_Manager::DataBlock_Manager(Fs *fs, u_int64_t block_segment_start,
u_int64_t block_segment_end)
: fs(fs), block_segment_start(block_segment_start),
block_segment_end(block_segment_end) {}
class BitmapBlock_Data {
public:
char buf[IO_BLOCK_SIZE];
u_int64_t datablocks_per_bitmap;
BitmapBlock_Data(u_int64_t datablocks_per_bitmap_)
: datablocks_per_bitmap(datablocks_per_bitmap_) {}
u_int64_t get_next_node() {
u_int64_t block_num;
read_u64(&block_num, buf);
return block_num;
}
void set_next_node(u_int64_t block_num) { write_u64(block_num, buf); }
u_int64_t find_unfilled() {
const char *data = &buf[8];
u_int64_t i = 0;
for (; i < datablocks_per_bitmap; ++i)
if ((data[i / 8] & (1 << (i % 8))) == 0)
return i + 1;
return 0;
}
u_int64_t claim_relative_block() {
u_int64_t unfilled = find_unfilled();
if (unfilled)
buf[((unfilled - 1) / 8) + 8] |= (1 << ((unfilled - 1) % 8));
return unfilled;
}
void release_relative_block(u_int64_t relative_block_num) {
relative_block_num -= 1;
size_t index = (relative_block_num / 8) + 8;
int offset = relative_block_num % 8;
buf[index] &= ~(1 << offset);
}
};
int DataBlock_Manager_Bitmap::new_datablock(u_int64_t *block_num) {
int err;
BitmapBlock_Data bitmap = BitmapBlock_Data(DATABLOCKS_PER_BITMAP_BLOCK);
u_int64_t bitmap_block_num = fs->superblock.free_list_head;
char zero_buf[IO_BLOCK_SIZE] = {0};
if (bitmap_block_num < block_segment_start ||
bitmap_block_num >= block_segment_end)
return -1;
if ((err = fs->disk->read_block(bitmap_block_num, bitmap.buf)) < 0)
return err;
u_int64_t relative_block_num = bitmap.claim_relative_block();
if (relative_block_num == 0)
return -1;
u_int64_t block_num_ = relative_block_num + bitmap_block_num;
// NOTE: this could be removed for speed
if ((err = fs->disk->write_block(block_num_, zero_buf)) < 0)
return err;
// Could be optimized
if (bitmap.find_unfilled() == 0) {
if ((err = fs->save_free_list_head(bitmap.get_next_node())) < 0)
return err;
bitmap.set_next_node(0);
}
if ((err = fs->disk->write_block(bitmap_block_num, bitmap.buf)) < 0)
return err;
(*block_num) = block_num_;
return 0;
}
int DataBlock_Manager_Bitmap::free_datablock(u_int64_t block_num) {
int err;
BitmapBlock_Data bitmap = BitmapBlock_Data(DATABLOCKS_PER_BITMAP_BLOCK);
const u_int64_t bitmap_region_size = DATABLOCKS_PER_BITMAP_BLOCK + 1;
bool update_freelist = false;
u_int64_t bitmap_block_num =
(((block_num - block_segment_start) / bitmap_region_size) *
bitmap_region_size) +
block_segment_start;
if ((err = fs->disk->read_block(bitmap_block_num, bitmap.buf)) < 0)
return err;
if (bitmap.find_unfilled() == 0) {
update_freelist = true;
bitmap.set_next_node(fs->superblock.free_list_head);
}
bitmap.release_relative_block(block_num - bitmap_block_num);
if ((err = fs->disk->write_block(bitmap_block_num, bitmap.buf)) < 0)
return err;
if (update_freelist)
if ((err = fs->save_free_list_head(bitmap_block_num)) < 0)
return err;
return 0;
// placing almost full bitmaps back at start of freelist is slow
// potentially like 256 times slower throughput
}
int DataBlock_Manager_Bitmap::format() {
const u_int64_t bitmap_region_size = DATABLOCKS_PER_BITMAP_BLOCK + 1;
char buf[IO_BLOCK_SIZE] = {0};
int err;
u_int64_t i = block_segment_start;
for (; i <= block_segment_end - (2 * bitmap_region_size);
i += bitmap_region_size) {
write_u64(i + bitmap_region_size, buf);
if ((err = fs->disk->write_block(i, buf)) < 0)
return err;
}
if ((err = fs->disk->write_block(i, buf)) < 0)
return err;
if ((err = fs->save_free_list_head(block_segment_start)) < 0)
return err;
return 0;
#include "fs.hpp"
DataBlock_Manager::DataBlock_Manager(Fs *fs, u_int64_t block_segment_start,
u_int64_t block_segment_end)
: fs(fs), block_segment_start(block_segment_start),
block_segment_end(block_segment_end) {}
class BitmapBlock_Data {
public:
char buf[IO_BLOCK_SIZE];
u_int64_t datablocks_per_bitmap;
BitmapBlock_Data(u_int64_t datablocks_per_bitmap_)
: datablocks_per_bitmap(datablocks_per_bitmap_) {}
u_int64_t get_next_node() {
u_int64_t block_num;
read_u64(&block_num, buf);
return block_num;
}
void set_next_node(u_int64_t block_num) { write_u64(block_num, buf); }
u_int64_t find_unfilled() {
const char *data = &buf[8];
u_int64_t i = 0;
for (; i < datablocks_per_bitmap; ++i)
if ((data[i / 8] & (1 << (i % 8))) == 0)
return i + 1;
return 0;
}
u_int64_t claim_relative_block() {
u_int64_t unfilled = find_unfilled();
if (unfilled)
buf[((unfilled - 1) / 8) + 8] |= (1 << ((unfilled - 1) % 8));
return unfilled;
}
void release_relative_block(u_int64_t relative_block_num) {
relative_block_num -= 1;
size_t index = (relative_block_num / 8) + 8;
int offset = relative_block_num % 8;
buf[index] &= ~(1 << offset);
}
};
int DataBlock_Manager_Bitmap::new_datablock(u_int64_t *block_num) {
int err;
BitmapBlock_Data bitmap = BitmapBlock_Data(DATABLOCKS_PER_BITMAP_BLOCK);
u_int64_t bitmap_block_num = fs->superblock.free_list_head;
char zero_buf[IO_BLOCK_SIZE] = {0};
if (bitmap_block_num < block_segment_start ||
bitmap_block_num >= block_segment_end)
return -1;
if ((err = fs->disk->read_block(bitmap_block_num, bitmap.buf)) < 0)
return err;
u_int64_t relative_block_num = bitmap.claim_relative_block();
if (relative_block_num == 0)
return -1;
u_int64_t block_num_ = relative_block_num + bitmap_block_num;
// NOTE: this could be removed for speed
if ((err = fs->disk->write_block(block_num_, zero_buf)) < 0)
return err;
// Could be optimized
if (bitmap.find_unfilled() == 0) {
if ((err = fs->save_free_list_head(bitmap.get_next_node())) < 0)
return err;
bitmap.set_next_node(0);
}
if ((err = fs->disk->write_block(bitmap_block_num, bitmap.buf)) < 0)
return err;
(*block_num) = block_num_;
return 0;
}
int DataBlock_Manager_Bitmap::free_datablock(u_int64_t block_num) {
int err;
BitmapBlock_Data bitmap = BitmapBlock_Data(DATABLOCKS_PER_BITMAP_BLOCK);
const u_int64_t bitmap_region_size = DATABLOCKS_PER_BITMAP_BLOCK + 1;
bool update_freelist = false;
u_int64_t bitmap_block_num =
(((block_num - block_segment_start) / bitmap_region_size) *
bitmap_region_size) +
block_segment_start;
if ((err = fs->disk->read_block(bitmap_block_num, bitmap.buf)) < 0)
return err;
if (bitmap.find_unfilled() == 0) {
update_freelist = true;
bitmap.set_next_node(fs->superblock.free_list_head);
}
bitmap.release_relative_block(block_num - bitmap_block_num);
if ((err = fs->disk->write_block(bitmap_block_num, bitmap.buf)) < 0)
return err;
if (update_freelist)
if ((err = fs->save_free_list_head(bitmap_block_num)) < 0)
return err;
return 0;
// placing almost full bitmaps back at start of freelist is slow
// potentially like 256 times slower throughput
}
int DataBlock_Manager_Bitmap::format() {
const u_int64_t bitmap_region_size = DATABLOCKS_PER_BITMAP_BLOCK + 1;
char buf[IO_BLOCK_SIZE] = {0};
int err;
u_int64_t i = block_segment_start;
for (; i <= block_segment_end - (2 * bitmap_region_size);
i += bitmap_region_size) {
write_u64(i + bitmap_region_size, buf);
if ((err = fs->disk->write_block(i, buf)) < 0)
return err;
}
if ((err = fs->disk->write_block(i, buf)) < 0)
return err;
if ((err = fs->save_free_list_head(block_segment_start)) < 0)
return err;
return 0;
}

View File

@ -1,132 +1,132 @@
#include "fs.hpp"
INode_Manager::INode_Manager(Fs *fs, u_int64_t block_segment_start,
u_int64_t block_segment_end)
: fs(fs), block_segment_start(block_segment_start),
block_segment_end(block_segment_end) {
max_num_inodes = (block_segment_end - block_segment_start) * INODES_PER_BLOCK;
}
u_int64_t INode_Manager::get_block_num(u_int64_t inode_num) {
u_int64_t block_num = block_segment_start + (inode_num / INODES_PER_BLOCK);
if (block_num >= block_segment_end)
return 0;
return block_num;
}
u_int64_t INode_Manager::get_block_offset(u_int64_t inode_num) {
return (inode_num % INODES_PER_BLOCK) * INODE_SIZE;
}
int INode_Manager::load_inode(INode_Data *inode_data) {
char buf[IO_BLOCK_SIZE];
int err;
u_int64_t block_num = get_block_num(inode_data->inode_num);
if (block_num == 0)
return -1;
u_int64_t block_offset = get_block_offset(inode_data->inode_num);
if ((err = fs->disk->read_block(block_num, buf)) < 0)
return err;
inode_data->deserialize(&buf[block_offset]);
return 0;
}
int INode_Manager::save_inode(INode_Data *inode_data) {
char buf[IO_BLOCK_SIZE];
int err;
u_int64_t block_num = get_block_num(inode_data->inode_num);
if (block_num == 0)
return -1;
u_int64_t block_offset = get_block_offset(inode_data->inode_num);
if ((err = fs->disk->read_block(block_num, buf)) < 0)
return err;
inode_data->serialize(&buf[block_offset]);
if ((err = fs->disk->write_block(block_num, buf)) < 0)
return err;
return 0;
}
int INode_Manager_Freelist::new_inode(u_int64_t uid, u_int64_t gid,
u_int64_t permissions,
INode_Data *inode_data) {
char buf[IO_BLOCK_SIZE];
int err;
u_int64_t inode_num = fs->superblock.inode_list_head;
if (inode_num > max_num_inodes)
return -1;
u_int64_t block_num = get_block_num(inode_num);
u_int64_t block_offset = get_block_offset(inode_num);
if (block_num == 0)
return -1;
if ((err = fs->disk->read_block(block_num, buf)) < 0)
return err;
u_int64_t new_inode_list_head = 0;
read_u64(&new_inode_list_head, &buf[block_offset]);
if ((err = fs->save_inode_list_head(new_inode_list_head)) < 0)
return err;
(*inode_data) = INode_Data(inode_num);
inode_data->metadata.uid = uid;
inode_data->metadata.gid = gid;
inode_data->metadata.permissions = permissions;
// It is debatable if this function should do this:
if ((err = save_inode(inode_data)) < 0) {
inode_data->inode_num = 0xFFFFFFFFFFFFFFFF;
return err;
}
return 0;
}
int INode_Manager_Freelist::free_inode(INode_Data *inode_data) {
char buf[IO_BLOCK_SIZE];
int err;
u_int64_t block_num = get_block_num(inode_data->inode_num);
u_int64_t block_offset = get_block_offset(inode_data->inode_num);
if (block_num == 0)
return -1;
if ((err = fs->disk->read_block(block_num, buf)) < 0)
return err;
write_u64(fs->superblock.inode_list_head, &buf[block_offset]);
if ((err = fs->disk->write_block(block_num, buf)) < 0)
return err;
if ((err = fs->save_inode_list_head(inode_data->inode_num)) < 0)
return err;
return 0;
}
int INode_Manager_Freelist::format() {
char buf[IO_BLOCK_SIZE];
int err;
u_int64_t next_inode_num = 1;
for (u_int64_t i = block_segment_start; i < block_segment_end; ++i) {
for (int j = 0; j < INODES_PER_BLOCK; ++next_inode_num, ++j)
write_u64(next_inode_num, &buf[j * INODE_SIZE]);
if ((err = fs->disk->write_block(i, buf)) < 0)
return err;
}
if ((err = fs->save_inode_list_head(0)) < 0)
return err;
return 0;
}
#include "fs.hpp"
INode_Manager::INode_Manager(Fs *fs, u_int64_t block_segment_start,
u_int64_t block_segment_end)
: fs(fs), block_segment_start(block_segment_start),
block_segment_end(block_segment_end) {
max_num_inodes = (block_segment_end - block_segment_start) * INODES_PER_BLOCK;
}
u_int64_t INode_Manager::get_block_num(u_int64_t inode_num) {
u_int64_t block_num = block_segment_start + (inode_num / INODES_PER_BLOCK);
if (block_num >= block_segment_end)
return 0;
return block_num;
}
u_int64_t INode_Manager::get_block_offset(u_int64_t inode_num) {
return (inode_num % INODES_PER_BLOCK) * INODE_SIZE;
}
int INode_Manager::load_inode(INode_Data *inode_data) {
char buf[IO_BLOCK_SIZE];
int err;
u_int64_t block_num = get_block_num(inode_data->inode_num);
if (block_num == 0)
return -1;
u_int64_t block_offset = get_block_offset(inode_data->inode_num);
if ((err = fs->disk->read_block(block_num, buf)) < 0)
return err;
inode_data->deserialize(&buf[block_offset]);
return 0;
}
int INode_Manager::save_inode(INode_Data *inode_data) {
char buf[IO_BLOCK_SIZE];
int err;
u_int64_t block_num = get_block_num(inode_data->inode_num);
if (block_num == 0)
return -1;
u_int64_t block_offset = get_block_offset(inode_data->inode_num);
if ((err = fs->disk->read_block(block_num, buf)) < 0)
return err;
inode_data->serialize(&buf[block_offset]);
if ((err = fs->disk->write_block(block_num, buf)) < 0)
return err;
return 0;
}
int INode_Manager_Freelist::new_inode(u_int64_t uid, u_int64_t gid,
u_int64_t permissions,
INode_Data *inode_data) {
char buf[IO_BLOCK_SIZE];
int err;
u_int64_t inode_num = fs->superblock.inode_list_head;
if (inode_num > max_num_inodes)
return -1;
u_int64_t block_num = get_block_num(inode_num);
u_int64_t block_offset = get_block_offset(inode_num);
if (block_num == 0)
return -1;
if ((err = fs->disk->read_block(block_num, buf)) < 0)
return err;
u_int64_t new_inode_list_head = 0;
read_u64(&new_inode_list_head, &buf[block_offset]);
if ((err = fs->save_inode_list_head(new_inode_list_head)) < 0)
return err;
(*inode_data) = INode_Data(inode_num);
inode_data->metadata.uid = uid;
inode_data->metadata.gid = gid;
inode_data->metadata.permissions = permissions;
// It is debatable if this function should do this:
if ((err = save_inode(inode_data)) < 0) {
inode_data->inode_num = 0xFFFFFFFFFFFFFFFF;
return err;
}
return 0;
}
int INode_Manager_Freelist::free_inode(INode_Data *inode_data) {
char buf[IO_BLOCK_SIZE];
int err;
u_int64_t block_num = get_block_num(inode_data->inode_num);
u_int64_t block_offset = get_block_offset(inode_data->inode_num);
if (block_num == 0)
return -1;
if ((err = fs->disk->read_block(block_num, buf)) < 0)
return err;
write_u64(fs->superblock.inode_list_head, &buf[block_offset]);
if ((err = fs->disk->write_block(block_num, buf)) < 0)
return err;
if ((err = fs->save_inode_list_head(inode_data->inode_num)) < 0)
return err;
return 0;
}
int INode_Manager_Freelist::format() {
char buf[IO_BLOCK_SIZE];
int err;
u_int64_t next_inode_num = 1;
for (u_int64_t i = block_segment_start; i < block_segment_end; ++i) {
for (int j = 0; j < INODES_PER_BLOCK; ++next_inode_num, ++j)
write_u64(next_inode_num, &buf[j * INODE_SIZE]);
if ((err = fs->disk->write_block(i, buf)) < 0)
return err;
}
if ((err = fs->save_inode_list_head(0)) < 0)
return err;
return 0;
}