iloveos/lib/fs/fs_resize.cpp
2023-11-17 01:33:19 -08:00

141 lines
3.6 KiB
C++

#include "fs.hpp"
int Fs::allocate_datablock(INode_Data *inode_data, u_int64_t *datablock_num) {
int result;
for (size_t i = 0; i < NUMBER_OF_DIRECT_BLOCKS; ++i) {
result =
allocate_indirect(&(inode_data->direct_blocks[i]), 0, datablock_num);
if (result <= 0)
return result;
}
result =
allocate_indirect(&(inode_data->single_indirect_block), 1, datablock_num);
if (result <= 0)
return result;
result =
allocate_indirect(&(inode_data->double_indirect_block), 2, datablock_num);
if (result <= 0)
return result;
result =
allocate_indirect(&(inode_data->triple_indirect_block), 3, datablock_num);
if (result <= 0)
return result;
return -1;
}
// This can simply be made non recursive by copy pasting - it is just written
// this way as a proof of concept
int Fs::allocate_indirect(u_int64_t *storage, int n, u_int64_t *datablock_num) {
char buf[IO_BLOCK_SIZE];
int result;
if ((*storage) == 0) {
if ((result = datablock_manager->new_datablock(storage)) < 0)
return result;
if (n == 0) {
(*datablock_num) = (*storage);
return 0;
}
}
if (n == 0)
return 1;
u_int64_t temp;
if ((result = disk->read_block(*storage, buf)) < 0)
return result;
for (size_t i = 0; i < IO_BLOCK_SIZE; i += sizeof(u_int64_t)) {
read_u64(&temp, &buf[i]);
result = allocate_indirect(&temp, n - 1, datablock_num);
if (result < 0)
return result;
if (result == 0) {
write_u64(temp, &buf[i]);
if ((result = disk->write_block(*storage, buf)) < 0)
return result;
return 0;
}
}
return 1;
}
int Fs::deallocate_datablock(INode_Data *inode_data, u_int64_t *datablock_num) {
int result;
result = deallocate_indirect(&(inode_data->triple_indirect_block), 3,
datablock_num);
if (result <= 0)
return result;
result = deallocate_indirect(&(inode_data->double_indirect_block), 2,
datablock_num);
if (result <= 0)
return result;
result = deallocate_indirect(&(inode_data->single_indirect_block), 1,
datablock_num);
if (result <= 0)
return result;
for (size_t i = NUMBER_OF_DIRECT_BLOCKS - 1; i >= 0; --i) {
result =
deallocate_indirect(&(inode_data->direct_blocks[i]), 0, datablock_num);
if (result <= 0)
return result;
}
return -1;
}
int Fs::deallocate_indirect(u_int64_t *storage, int n,
u_int64_t *datablock_num) {
char buf[IO_BLOCK_SIZE];
int result;
if (*storage == 0)
return 1;
if (n == 0) {
u_int64_t temp_datablock_num = (*storage);
if ((result = datablock_manager->free_datablock(*storage)) < 0)
return result;
(*datablock_num) = temp_datablock_num;
(*storage) = 0;
return 0;
}
u_int64_t temp;
if ((result = disk->read_block(*storage, buf)) < 0)
return result;
for (size_t i = IO_BLOCK_SIZE - sizeof(u_int64_t); i >= 0;
i -= sizeof(u_int64_t)) {
read_u64(&temp, &buf[i]);
result = deallocate_indirect(&temp, n - 1, datablock_num);
if (result < 0)
return result;
if (result == 0) {
if (i == 0 && temp == 0) {
if ((result = datablock_manager->free_datablock(*storage)) < 0)
return result;
(*storage) = 0;
} else {
write_u64(temp, &buf[i]);
if ((result = disk->write_block(*storage, buf)) < 0)
return result;
}
return 0;
}
}
return 1;
}