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/fischl.cpp
lib/main.cpp lib/main.cpp
lib/rawdisk.cpp lib/rawdisk.cpp
lib/fs/datablock_allocator.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_resize.cpp
lib/fs/fs.cpp lib/fs/fs.cpp
lib/fs/inode_allocator.cpp lib/fs/inode_manager.cpp
) )

View File

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

View File

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