iloveos/lib/fs/datablock_allocator.cpp

75 lines
2.1 KiB
C++

#include "fs.hpp"
DataBlock_Allocator::DataBlock_Allocator(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 {
char buf[BLOCK_SIZE];
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 claim_relative_block() {
// This type u_int64_t is important
u_int64_t *data = &buf[8];
u_int64_t relative_block_num = 0;
for (size_t i = 0; i < (BLOCK_SIZE / 8) - 1; ++i)
if (data[i] != (~0))
for (size_t j = 0; j < 64; ++j)
if (data[i] & (1 << j)) {
data[i] |= (1 << j);
return (i * 64) + j + 1;
}
perror("Error claiming block from bitmap");
return 0;
}
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_Allocator_Bitmap::new_datablock(u_int64_t *block_num) {
int err;
BitmapBlock_Data bitmap = BitmapBlock_Data();
u_int64_t bitmap_block_num = fs->superblock.free_list_head;
if ((err = 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 == DATABLOCKS_PER_BITMAP_BLOCK) {
fs->superblock.free_list_head = bitmap.get_next_node();
if ((err = fs->store_superblock()) < 0)
return err;
}
bitmap.set_next_node(0);
if ((err = disk->write_block(bitmap_block_num, bitmap.buf)) < 0)
return err;
(*block_num) = relative_block_num + bitmap_block_num;
return 0;
}
int DataBlock_Allocator_Bitmap::free_datablock(u_int64_t block_num) {
return -1;
// sticing almost full bitmaps back at start of freelist os slow
// also potentially like 256 times slower
}
int DataBlock_Allocator_Bitmap::format() { return -1; }