iloveos/lib/fs/fs.cpp

91 lines
2.4 KiB
C++

#include "fs.hpp"
#include <assert.h>
Fs::Fs(RawDisk *disk, bool load, uint64_t user_inode_blocks) : disk(disk) {
superblock = SuperBlock_Data();
// Determine the num inode blocks
uint64_t num_inode_blocks = 0; // The superblock is not loaded from disk here; it is done in FilesOperation::initialize called by fischl_init
if(load) {
load_superblock();
num_inode_blocks = superblock.num_inode_blocks;
} else {
num_inode_blocks = user_inode_blocks;
superblock.num_inode_blocks = num_inode_blocks;
superblock.num_used_inodes = 0;
superblock.num_data_blocks = disk->diskSize / IO_BLOCK_SIZE - 1 - num_inode_blocks;
superblock.num_used_data_blocks = 0;
}
assert((disk->diskSize / IO_BLOCK_SIZE) >
2 + num_inode_blocks + DATABLOCKS_PER_BITMAP_BLOCK);
inode_manager = new INode_Manager_Freelist(this, 1, 1 + num_inode_blocks);
datablock_manager = new DataBlock_Manager_Bitmap(
this, 1 + num_inode_blocks, disk->diskSize / IO_BLOCK_SIZE);
};
Fs::~Fs() {
delete inode_manager;
delete datablock_manager;
};
int Fs::format() {
int err;
if ((err = save_superblock()) < 0)
return err;
if ((err = inode_manager->format()) < 0)
return err;
if ((err = datablock_manager->format()) < 0)
return err;
return 0;
}
int Fs::load_superblock() {
char buf[IO_BLOCK_SIZE];
int err;
if ((err = disk->read_block(0, buf)) < 0)
return err;
superblock.deserialize(buf);
return 0;
}
int Fs::save_superblock() {
char buf[IO_BLOCK_SIZE] = {0};
int err;
superblock.serialize(buf);
if ((err = disk->write_block(0, buf)) < 0)
return err;
return 0;
}
int Fs::save_free_list_head(u_int64_t new_free_list_head) {
u_int64_t temp = superblock.free_list_head;
int err;
superblock.free_list_head = new_free_list_head;
if ((err = save_superblock()) < 0) {
superblock.free_list_head = temp;
return err;
}
return 0;
}
int Fs::save_inode_list_head(u_int64_t new_inode_list_head) {
u_int64_t temp = superblock.inode_list_head;
int err;
superblock.inode_list_head = new_inode_list_head;
if ((err = save_superblock()) < 0) {
superblock.inode_list_head = temp;
return err;
}
return 0;
}
void Fs::update_num_used_inodes(int delta) {
superblock.num_used_inodes += delta;
}
void Fs::update_num_used_datablocks(int delta) {
superblock.num_used_data_blocks += delta;
}