141 lines
3.6 KiB
C++
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;
|
|
} |