half of tests added
This commit is contained in:
parent
b921cadf92
commit
9ed5936762
@ -21,5 +21,5 @@ add_executable(fischl
|
|||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
#enable_testing()
|
enable_testing()
|
||||||
#add_subdirectory(test)
|
add_subdirectory(test)
|
@ -12,8 +12,8 @@ public:
|
|||||||
Fs(RawDisk *disk);
|
Fs(RawDisk *disk);
|
||||||
~Fs();
|
~Fs();
|
||||||
|
|
||||||
int allocate_datablock(INode_Data *inode_data);
|
int allocate_datablock(INode_Data *inode_data, u_int64_t *datablock_num);
|
||||||
int deallocate_datablock(INode_Data *inode_data);
|
int deallocate_datablock(INode_Data *inode_data, u_int64_t *datablock_num);
|
||||||
|
|
||||||
int format();
|
int format();
|
||||||
|
|
||||||
@ -29,8 +29,8 @@ public:
|
|||||||
int save_free_list_head(u_int64_t new_free_list_head);
|
int save_free_list_head(u_int64_t new_free_list_head);
|
||||||
int save_inode_list_head(u_int64_t new_inode_list_head);
|
int save_inode_list_head(u_int64_t new_inode_list_head);
|
||||||
|
|
||||||
int allocate_indirect(u_int64_t *storage, int n);
|
int allocate_indirect(u_int64_t *storage, int n, u_int64_t *datablock_num);
|
||||||
int deallocate_indirect(u_int64_t *storage, int n);
|
int deallocate_indirect(u_int64_t *storage, int n, u_int64_t *datablock_num);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -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;
|
||||||
}
|
}
|
@ -1,25 +1,27 @@
|
|||||||
#include "fs.hpp"
|
#include "fs.hpp"
|
||||||
|
|
||||||
int Fs::allocate_datablock(INode_Data *inode_data) {
|
int Fs::allocate_datablock(INode_Data *inode_data, u_int64_t *datablock_num) {
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
for (size_t i = 0; i < NUMBER_OF_DIRECT_BLOCKS; ++i)
|
for (size_t i = 0; i < NUMBER_OF_DIRECT_BLOCKS; ++i) {
|
||||||
if (inode_data->direct_blocks[i] == 0) {
|
result =
|
||||||
if ((result = datablock_manager->new_datablock(
|
allocate_indirect(&(inode_data->direct_blocks[i]), 0, datablock_num);
|
||||||
&(inode_data->direct_blocks[i]))) < 0)
|
if (result <= 0)
|
||||||
return result;
|
return result;
|
||||||
return 0;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
result = allocate_indirect(&(inode_data->single_indirect_block), 1);
|
result =
|
||||||
|
allocate_indirect(&(inode_data->single_indirect_block), 1, datablock_num);
|
||||||
if (result <= 0)
|
if (result <= 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
result = allocate_indirect(&(inode_data->double_indirect_block), 2);
|
result =
|
||||||
|
allocate_indirect(&(inode_data->double_indirect_block), 2, datablock_num);
|
||||||
if (result <= 0)
|
if (result <= 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
result = allocate_indirect(&(inode_data->triple_indirect_block), 3);
|
result =
|
||||||
|
allocate_indirect(&(inode_data->triple_indirect_block), 3, datablock_num);
|
||||||
if (result <= 0)
|
if (result <= 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
@ -28,15 +30,17 @@ int Fs::allocate_datablock(INode_Data *inode_data) {
|
|||||||
|
|
||||||
// This can simply be made non recursive by copy pasting - it is just written
|
// This can simply be made non recursive by copy pasting - it is just written
|
||||||
// this way as a proof of concept
|
// this way as a proof of concept
|
||||||
int Fs::allocate_indirect(u_int64_t *storage, int n) {
|
int Fs::allocate_indirect(u_int64_t *storage, int n, u_int64_t *datablock_num) {
|
||||||
char buf[IO_BLOCK_SIZE];
|
char buf[IO_BLOCK_SIZE];
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if ((*storage) == 0) {
|
if ((*storage) == 0) {
|
||||||
if ((result = datablock_manager->new_datablock(storage)) < 0)
|
if ((result = datablock_manager->new_datablock(storage)) < 0)
|
||||||
return result;
|
return result;
|
||||||
if (n == 0)
|
if (n == 0) {
|
||||||
|
(*datablock_num) = (*storage);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
@ -49,7 +53,7 @@ int Fs::allocate_indirect(u_int64_t *storage, int n) {
|
|||||||
|
|
||||||
for (size_t i = 0; i < IO_BLOCK_SIZE; i += sizeof(u_int64_t)) {
|
for (size_t i = 0; i < IO_BLOCK_SIZE; i += sizeof(u_int64_t)) {
|
||||||
read_u64(&temp, &buf[i]);
|
read_u64(&temp, &buf[i]);
|
||||||
result = allocate_indirect(&temp, n - 1);
|
result = allocate_indirect(&temp, n - 1, datablock_num);
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
return result;
|
return result;
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
@ -63,34 +67,36 @@ int Fs::allocate_indirect(u_int64_t *storage, int n) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Fs::deallocate_datablock(INode_Data *inode_data) {
|
int Fs::deallocate_datablock(INode_Data *inode_data, u_int64_t *datablock_num) {
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
result = deallocate_indirect(&(inode_data->triple_indirect_block), 3);
|
result = deallocate_indirect(&(inode_data->triple_indirect_block), 3,
|
||||||
|
datablock_num);
|
||||||
if (result <= 0)
|
if (result <= 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
result = deallocate_indirect(&(inode_data->double_indirect_block), 2);
|
result = deallocate_indirect(&(inode_data->double_indirect_block), 2,
|
||||||
|
datablock_num);
|
||||||
if (result <= 0)
|
if (result <= 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
result = deallocate_indirect(&(inode_data->single_indirect_block), 1);
|
result = deallocate_indirect(&(inode_data->single_indirect_block), 1,
|
||||||
|
datablock_num);
|
||||||
if (result <= 0)
|
if (result <= 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
for (size_t i = NUMBER_OF_DIRECT_BLOCKS - 1; i >= 0; --i)
|
for (size_t i = NUMBER_OF_DIRECT_BLOCKS - 1; i >= 0; --i) {
|
||||||
if (inode_data->direct_blocks[i] != 0) {
|
result =
|
||||||
if ((result = datablock_manager->free_datablock(
|
deallocate_indirect(&(inode_data->direct_blocks[i]), 0, datablock_num);
|
||||||
inode_data->direct_blocks[i])) < 0)
|
if (result <= 0)
|
||||||
return result;
|
return result;
|
||||||
inode_data->direct_blocks[i] = 0;
|
}
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Fs::deallocate_indirect(u_int64_t *storage, int n) {
|
int Fs::deallocate_indirect(u_int64_t *storage, int n,
|
||||||
|
u_int64_t *datablock_num) {
|
||||||
char buf[IO_BLOCK_SIZE];
|
char buf[IO_BLOCK_SIZE];
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
@ -98,8 +104,10 @@ int Fs::deallocate_indirect(u_int64_t *storage, int n) {
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
|
u_int64_t temp_datablock_num = (*storage);
|
||||||
if ((result = datablock_manager->free_datablock(*storage)) < 0)
|
if ((result = datablock_manager->free_datablock(*storage)) < 0)
|
||||||
return result;
|
return result;
|
||||||
|
(*datablock_num) = temp_datablock_num;
|
||||||
(*storage) = 0;
|
(*storage) = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -112,7 +120,7 @@ int Fs::deallocate_indirect(u_int64_t *storage, int n) {
|
|||||||
for (size_t i = IO_BLOCK_SIZE - sizeof(u_int64_t); i >= 0;
|
for (size_t i = IO_BLOCK_SIZE - sizeof(u_int64_t); i >= 0;
|
||||||
i -= sizeof(u_int64_t)) {
|
i -= sizeof(u_int64_t)) {
|
||||||
read_u64(&temp, &buf[i]);
|
read_u64(&temp, &buf[i]);
|
||||||
result = deallocate_indirect(&temp, n - 1);
|
result = deallocate_indirect(&temp, n - 1, datablock_num);
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
return result;
|
return result;
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
|
@ -1,132 +1,134 @@
|
|||||||
#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);
|
if (inode_num > max_num_inodes || inode_num == 0)
|
||||||
if (block_num >= block_segment_end)
|
return 0;
|
||||||
return 0;
|
u_int64_t block_num =
|
||||||
return block_num;
|
block_segment_start + ((inode_num - 1) / INODES_PER_BLOCK);
|
||||||
}
|
return block_num;
|
||||||
u_int64_t INode_Manager::get_block_offset(u_int64_t inode_num) {
|
}
|
||||||
return (inode_num % INODES_PER_BLOCK) * INODE_SIZE;
|
u_int64_t INode_Manager::get_block_offset(u_int64_t inode_num) {
|
||||||
}
|
return ((inode_num - 1) % INODES_PER_BLOCK) * INODE_SIZE;
|
||||||
|
}
|
||||||
int INode_Manager::load_inode(INode_Data *inode_data) {
|
|
||||||
char buf[IO_BLOCK_SIZE];
|
int INode_Manager::load_inode(INode_Data *inode_data) {
|
||||||
int err;
|
char buf[IO_BLOCK_SIZE];
|
||||||
|
int err;
|
||||||
u_int64_t block_num = get_block_num(inode_data->inode_num);
|
|
||||||
if (block_num == 0)
|
u_int64_t block_num = get_block_num(inode_data->inode_num);
|
||||||
return -1;
|
if (block_num == 0)
|
||||||
u_int64_t block_offset = get_block_offset(inode_data->inode_num);
|
return -1;
|
||||||
|
u_int64_t block_offset = get_block_offset(inode_data->inode_num);
|
||||||
if ((err = fs->disk->read_block(block_num, buf)) < 0)
|
|
||||||
return err;
|
if ((err = fs->disk->read_block(block_num, buf)) < 0)
|
||||||
|
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) {
|
}
|
||||||
char buf[IO_BLOCK_SIZE];
|
int INode_Manager::save_inode(INode_Data *inode_data) {
|
||||||
int err;
|
char buf[IO_BLOCK_SIZE];
|
||||||
|
int err;
|
||||||
u_int64_t block_num = get_block_num(inode_data->inode_num);
|
|
||||||
if (block_num == 0)
|
u_int64_t block_num = get_block_num(inode_data->inode_num);
|
||||||
return -1;
|
if (block_num == 0)
|
||||||
u_int64_t block_offset = get_block_offset(inode_data->inode_num);
|
return -1;
|
||||||
|
u_int64_t block_offset = get_block_offset(inode_data->inode_num);
|
||||||
if ((err = fs->disk->read_block(block_num, buf)) < 0)
|
|
||||||
return err;
|
if ((err = fs->disk->read_block(block_num, buf)) < 0)
|
||||||
|
return err;
|
||||||
inode_data->serialize(&buf[block_offset]);
|
|
||||||
|
inode_data->serialize(&buf[block_offset]);
|
||||||
if ((err = fs->disk->write_block(block_num, buf)) < 0)
|
|
||||||
return err;
|
if ((err = fs->disk->write_block(block_num, buf)) < 0)
|
||||||
|
return err;
|
||||||
return 0;
|
|
||||||
}
|
return 0;
|
||||||
|
}
|
||||||
int INode_Manager_Freelist::new_inode(u_int64_t uid, u_int64_t gid,
|
|
||||||
u_int64_t permissions,
|
int INode_Manager_Freelist::new_inode(u_int64_t uid, u_int64_t gid,
|
||||||
INode_Data *inode_data) {
|
u_int64_t permissions,
|
||||||
char buf[IO_BLOCK_SIZE];
|
INode_Data *inode_data) {
|
||||||
int err;
|
char buf[IO_BLOCK_SIZE];
|
||||||
u_int64_t inode_num = fs->superblock.inode_list_head;
|
int err;
|
||||||
if (inode_num > max_num_inodes)
|
u_int64_t inode_num = fs->superblock.inode_list_head;
|
||||||
return -1;
|
if (inode_num > max_num_inodes)
|
||||||
|
return -1;
|
||||||
u_int64_t block_num = get_block_num(inode_num);
|
|
||||||
u_int64_t block_offset = get_block_offset(inode_num);
|
u_int64_t block_num = get_block_num(inode_num);
|
||||||
|
u_int64_t block_offset = get_block_offset(inode_num);
|
||||||
if (block_num == 0)
|
|
||||||
return -1;
|
if (block_num == 0)
|
||||||
|
return -1;
|
||||||
if ((err = fs->disk->read_block(block_num, buf)) < 0)
|
|
||||||
return err;
|
if ((err = fs->disk->read_block(block_num, buf)) < 0)
|
||||||
|
return err;
|
||||||
u_int64_t new_inode_list_head = 0;
|
|
||||||
read_u64(&new_inode_list_head, &buf[block_offset]);
|
u_int64_t new_inode_list_head = 0;
|
||||||
if ((err = fs->save_inode_list_head(new_inode_list_head)) < 0)
|
read_u64(&new_inode_list_head, &buf[block_offset]);
|
||||||
return err;
|
if ((err = fs->save_inode_list_head(new_inode_list_head)) < 0)
|
||||||
|
return err;
|
||||||
(*inode_data) = INode_Data(inode_num);
|
|
||||||
|
(*inode_data) = INode_Data(inode_num);
|
||||||
inode_data->metadata.uid = uid;
|
|
||||||
inode_data->metadata.gid = gid;
|
inode_data->metadata.uid = uid;
|
||||||
inode_data->metadata.permissions = permissions;
|
inode_data->metadata.gid = gid;
|
||||||
|
inode_data->metadata.permissions = permissions;
|
||||||
// It is debatable if this function should do this:
|
|
||||||
if ((err = save_inode(inode_data)) < 0) {
|
// It is debatable if this function should do this:
|
||||||
inode_data->inode_num = 0xFFFFFFFFFFFFFFFF;
|
if ((err = save_inode(inode_data)) < 0) {
|
||||||
return err;
|
inode_data->inode_num = 0xFFFFFFFFFFFFFFFF;
|
||||||
}
|
return err;
|
||||||
|
}
|
||||||
return 0;
|
|
||||||
}
|
return 0;
|
||||||
int INode_Manager_Freelist::free_inode(INode_Data *inode_data) {
|
}
|
||||||
char buf[IO_BLOCK_SIZE];
|
int INode_Manager_Freelist::free_inode(INode_Data *inode_data) {
|
||||||
int err;
|
char buf[IO_BLOCK_SIZE];
|
||||||
|
int err;
|
||||||
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_num = get_block_num(inode_data->inode_num);
|
||||||
|
u_int64_t block_offset = get_block_offset(inode_data->inode_num);
|
||||||
if (block_num == 0)
|
|
||||||
return -1;
|
if (block_num == 0)
|
||||||
|
return -1;
|
||||||
if ((err = fs->disk->read_block(block_num, buf)) < 0)
|
|
||||||
return err;
|
if ((err = fs->disk->read_block(block_num, buf)) < 0)
|
||||||
|
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)
|
|
||||||
return err;
|
if ((err = fs->disk->write_block(block_num, buf)) < 0)
|
||||||
|
return err;
|
||||||
if ((err = fs->save_inode_list_head(inode_data->inode_num)) < 0)
|
|
||||||
return err;
|
if ((err = fs->save_inode_list_head(inode_data->inode_num)) < 0)
|
||||||
|
return err;
|
||||||
return 0;
|
|
||||||
}
|
return 0;
|
||||||
|
}
|
||||||
int INode_Manager_Freelist::format() {
|
|
||||||
char buf[IO_BLOCK_SIZE];
|
int INode_Manager_Freelist::format() {
|
||||||
int err;
|
char buf[IO_BLOCK_SIZE];
|
||||||
u_int64_t next_inode_num = 1;
|
int err;
|
||||||
for (u_int64_t i = block_segment_start; i < block_segment_end; ++i) {
|
u_int64_t next_inode_num = 2;
|
||||||
for (int j = 0; j < INODES_PER_BLOCK; ++next_inode_num, ++j)
|
for (u_int64_t i = block_segment_start; i < block_segment_end; ++i) {
|
||||||
write_u64(next_inode_num, &buf[j * INODE_SIZE]);
|
for (int j = 0; j < INODES_PER_BLOCK; ++next_inode_num, ++j) {
|
||||||
if ((err = fs->disk->write_block(i, buf)) < 0)
|
if (next_inode_num > max_num_inodes)
|
||||||
return err;
|
next_inode_num = 0;
|
||||||
}
|
write_u64(next_inode_num, &buf[j * INODE_SIZE]);
|
||||||
if ((err = fs->save_inode_list_head(0)) < 0)
|
}
|
||||||
return err;
|
if ((err = fs->disk->write_block(i, buf)) < 0)
|
||||||
return 0;
|
return err;
|
||||||
}
|
}
|
||||||
|
if ((err = fs->save_inode_list_head(1)) < 0)
|
||||||
|
return err;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -15,11 +15,12 @@ int main() {
|
|||||||
INode_Data inode_data = INode_Data();
|
INode_Data inode_data = INode_Data();
|
||||||
fs->inode_manager->new_inode(1, 2, 3, &inode_data);
|
fs->inode_manager->new_inode(1, 2, 3, &inode_data);
|
||||||
int err;
|
int err;
|
||||||
|
u_int64_t block_num = 0;
|
||||||
for (int i = 0; i < 56 + 512 + 4; ++i)
|
for (int i = 0; i < 56 + 512 + 4; ++i)
|
||||||
err = fs->allocate_datablock(&inode_data);
|
err = fs->allocate_datablock(&inode_data, &block_num);
|
||||||
|
|
||||||
for (int i = 0; i < 5; ++i)
|
for (int i = 0; i < 5; ++i)
|
||||||
printf("%d\n", err = fs->deallocate_datablock(&inode_data));
|
printf("%d\n", err = fs->deallocate_datablock(&inode_data, &block_num));
|
||||||
|
|
||||||
fs->inode_manager->save_inode(&inode_data);
|
fs->inode_manager->save_inode(&inode_data);
|
||||||
|
|
||||||
|
@ -12,7 +12,9 @@ void RawDisk::print_block(u_int64_t block_number) {
|
|||||||
|
|
||||||
printf("\nBlock %llu:\n", block_number);
|
printf("\nBlock %llu:\n", block_number);
|
||||||
for (int i = 0; i < IO_BLOCK_SIZE; i += sizeof(u_int64_t)) {
|
for (int i = 0; i < IO_BLOCK_SIZE; i += sizeof(u_int64_t)) {
|
||||||
read_u64(&num, &buf[i]);
|
num = 0;
|
||||||
|
for (int j = 0; j < 8; j++)
|
||||||
|
num |= ((u_int64_t)(unsigned char)buf[i + j]) << (8 * j);
|
||||||
printf("%llu ", num);
|
printf("%llu ", num);
|
||||||
if ((i / sizeof(u_int64_t)) % nums_per_line == nums_per_line - 1)
|
if ((i / sizeof(u_int64_t)) % nums_per_line == nums_per_line - 1)
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
@ -1,23 +1,34 @@
|
|||||||
set(TARGET_LAYER0 test_layer0)
|
set(TARGET_LAYER0 test_layer0)
|
||||||
set(TARGET_LAYER1_API test_layer1_API)
|
set(TARGET_LAYER1_API test_layer1_API)
|
||||||
set(TARGET_LAYER1_TEST1 test_layer1_test1)
|
# set(TARGET_LAYER1_TEST1 test_layer1_test1)
|
||||||
set(DIR_PLACE /dev/vdb)
|
set(DIR_PLACE /dev/vdb)
|
||||||
|
|
||||||
# add test sources here ...
|
# add test sources here ...
|
||||||
add_executable(${TARGET_LAYER0}
|
add_executable(${TARGET_LAYER0}
|
||||||
# add need lib and source code here
|
# add need lib and source code here
|
||||||
layer0.cpp
|
layer0.cpp
|
||||||
|
|
||||||
|
../lib/rawdisk.cpp
|
||||||
|
|
||||||
)
|
)
|
||||||
add_executable(${TARGET_LAYER1_API}
|
add_executable(${TARGET_LAYER1_API}
|
||||||
# add need lib and source code here
|
# add need lib and source code here
|
||||||
layer1_API.cpp
|
layer1_API.cpp
|
||||||
|
|
||||||
|
../lib/fischl.cpp
|
||||||
|
../lib/rawdisk.cpp
|
||||||
|
../lib/fs/datablock_manager.cpp
|
||||||
|
../lib/fs/fs_data_types.cpp
|
||||||
|
../lib/fs/fs_resize.cpp
|
||||||
|
../lib/fs/fs.cpp
|
||||||
|
../lib/fs/inode_manager.cpp
|
||||||
)
|
)
|
||||||
add_executable(${TARGET_LAYER1_TEST1}
|
# add_executable(${TARGET_LAYER1_TEST1}
|
||||||
# add need lib and source code here
|
# # add need lib and source code here
|
||||||
layer1_test1.cpp
|
# layer1_test1.cpp
|
||||||
)
|
# )
|
||||||
|
|
||||||
# add test to activate ctest -VV
|
# add test to activate ctest -VV
|
||||||
add_test(NAME ${TARGET_LAYER0} COMMAND sudo ./${TARGET_LAYER0} ${DIR_PLACE})
|
add_test(NAME ${TARGET_LAYER0} COMMAND sudo ./${TARGET_LAYER0} ${DIR_PLACE})
|
||||||
add_test(NAME ${TARGET_LAYER1_API} COMMAND sudo ./${TARGET_LAYER1_API} ${DIR_PLACE})
|
add_test(NAME ${TARGET_LAYER1_API} COMMAND sudo ./${TARGET_LAYER1_API} ${DIR_PLACE})
|
||||||
add_test(NAME ${TARGET_LAYER1_TEST1} COMMAND sudo ./${TARGET_LAYER1_TEST1} ${DIR_PLACE})
|
# add_test(NAME ${TARGET_LAYER1_TEST1} COMMAND sudo ./${TARGET_LAYER1_TEST1} ${DIR_PLACE})
|
@ -1,29 +1,32 @@
|
|||||||
|
#include "rawdisk.hpp"
|
||||||
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
|
||||||
#include "rawdisk.h"
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
const char* d = (argc < 2) ? "/dev/vdc" : argv[1];
|
const char *d = (argc < 2) ? "/dev/vdc" : argv[1];
|
||||||
|
|
||||||
RawDisk *H = new RawDisk(d);
|
|
||||||
|
|
||||||
char *buf = "iloveosdfjlseirfnerig";
|
|
||||||
char readBuffer[512] = {0}; // Initialize to zeros
|
|
||||||
|
|
||||||
//printf("dir %s, numSectors %lld, diskSize %lld \n", H->dir, H->numSectors, H->diskSize);
|
RawDisk *H = new RealRawDisk(d);
|
||||||
|
|
||||||
//use number to substitute H->getnumSector(), getnumSectors() are not yest implemented
|
char *buf = "iloveosdfjlseirfnerig";
|
||||||
for(u_int64_t i = 0; i < 10; i++) {
|
char readBuffer[IO_BLOCK_SIZE] = {0}; // Initialize to zeros
|
||||||
H->rawdisk_write(i*512, buf, strlen(buf));//Change write_API
|
|
||||||
}
|
|
||||||
//use number to substitute H->getnumSector(), getnumSectors() are not yest implemented
|
|
||||||
for(u_int64_t i = 0; i < 10; i++) {
|
|
||||||
H->rawdisk_read(i*512, readBuffer, sizeof(readBuffer));//Change read_API
|
|
||||||
assert(strncmp(readBuffer, buf, strlen(buf)) == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete H; // Delete the RawDisk object
|
// printf("dir %s, numSectors %lld, diskSize %lld \n", H->dir, H->numSectors,
|
||||||
|
// H->diskSize);
|
||||||
|
|
||||||
return 0;
|
// use number to substitute H->getnumSector(), getnumSectors() are not yest
|
||||||
|
// implemented
|
||||||
|
for (u_int64_t i = 0; i < 10; i++) {
|
||||||
|
H->write_block(i, buf); // Change write_API
|
||||||
|
}
|
||||||
|
// use number to substitute H->getnumSector(), getnumSectors() are not yest
|
||||||
|
// implemented
|
||||||
|
for (u_int64_t i = 0; i < 10; i++) {
|
||||||
|
H->read_block(i, readBuffer); // Change read_API
|
||||||
|
assert(strncmp(readBuffer, buf, strlen(buf)) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete H; // Delete the RawDisk object
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,118 +1,144 @@
|
|||||||
|
#include "fs.hpp"
|
||||||
|
#include <assert.h>
|
||||||
|
#include <inttypes.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
|
||||||
#include "fs.h"
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
const char* d = (argc < 2) ? "/dev/vdc" : argv[1];
|
// const char* d = (argc < 2) ? "/dev/vdc" : argv[1];
|
||||||
|
|
||||||
RawDisk *H = new RawDisk(d);
|
|
||||||
|
|
||||||
printf("test inode\n");
|
RawDisk *H = new FakeRawDisk(2048);
|
||||||
INodeOperation inop;
|
Fs *fs = new Fs(H);
|
||||||
inop.initialize(*H);//for inode initialization and datablock initialization
|
|
||||||
char buffer[8] = {0};
|
|
||||||
/**************************test inode Initialization***************************/
|
|
||||||
//test the begining of inode 1th
|
|
||||||
H->rawdisk_read((1) * SECTOR_SIZE, buffer, sizeof(buffer));
|
|
||||||
u_int64_t t = 0;
|
|
||||||
for (int j = 0; j < 8; j++)
|
|
||||||
t |= ((u_int64_t)(unsigned char)buffer[j]) << (8 * j);
|
|
||||||
|
|
||||||
assert(t == 2);//the first 1th unused inode will store the next unused inode 2th
|
printf("test inode\n");
|
||||||
//test the number before end of inode 524286th
|
fs->format();
|
||||||
H->rawdisk_read((MAX_INODE - 2) * SECTOR_SIZE, buffer, sizeof(buffer));
|
char buffer[IO_BLOCK_SIZE] = {0};
|
||||||
t = 0;
|
/**************************test inode
|
||||||
for (int j = 0; j < 8; j++)
|
* Initialization***************************/
|
||||||
t |= ((u_int64_t)(unsigned char)buffer[j]) << (8 * j);
|
// test the begining of inode 1th
|
||||||
|
H->read_block(1, buffer);
|
||||||
assert(t == MAX_INODE - 1);//store the maximun th inode
|
u_int64_t t = 0;
|
||||||
//test the end of inode 524287th
|
for (int j = 0; j < 8; j++)
|
||||||
H->rawdisk_read((MAX_INODE - 1) * SECTOR_SIZE, buffer, sizeof(buffer));
|
t |= ((u_int64_t)(unsigned char)buffer[j]) << (8 * j);
|
||||||
t = 0;
|
|
||||||
for (int j = 0; j < 8; j++)
|
|
||||||
t |= ((u_int64_t)(unsigned char)buffer[j]) << (8 * j);
|
|
||||||
|
|
||||||
assert(t == 0);//the end of inode(524287th inode) do not have the next inode address
|
assert(t ==
|
||||||
/**************************test datablock Initialization***************************/
|
2); // the first 1th unused inode will store the next unused inode 2th
|
||||||
//we separate 2048 4kB I/O block(1+2047) as a group and the first I/O block will manage the following 2047 I/O block usage.
|
|
||||||
//the first 8 bytes(0~7) in first I/O block store the address of next first I/O block, the following 256(8~263) bytes record 2047 I/O block usage.
|
|
||||||
//test the begining of free datablock
|
|
||||||
H->rawdisk_read((MAX_INODE) * SECTOR_SIZE, buffer, sizeof(buffer));//the begining of free datablock will store from address (MAX_INODE) * SECTOR_SIZE
|
|
||||||
t = 0;
|
|
||||||
for (int j = 0; j < 8; j++)
|
|
||||||
t |= ((u_int64_t)(unsigned char)buffer[j]) << (8 * j);
|
|
||||||
|
|
||||||
assert(t == (MAX_INODE+2048*8)*SECTOR_SIZE);//the first 8 bytes of 4k I/O block will store the next address(after 2048*4k I/O block)
|
assert(IO_BLOCK_SIZE == 4096);
|
||||||
//test the end of the datablock
|
assert(INODE_SIZE == 512);
|
||||||
H->rawdisk_read((MAX_BLOCKNUM - 2048*8) * SECTOR_SIZE, buffer, sizeof(buffer));
|
|
||||||
t = 0;
|
|
||||||
for (int j = 0; j < 8; j++)
|
|
||||||
t |= ((u_int64_t)(unsigned char)buffer[j]) << (8 * j);
|
|
||||||
|
|
||||||
assert(t == (MAX_BLOCKNUM)*SECTOR_SIZE);
|
// test the number before end of inode
|
||||||
|
H->read_block(NUM_INODE_BLOCKS, buffer);
|
||||||
|
t = 0;
|
||||||
|
for (int j = 0; j < 8; j++)
|
||||||
|
t |=
|
||||||
|
((u_int64_t)(unsigned char)buffer[j + IO_BLOCK_SIZE - (INODE_SIZE * 2)])
|
||||||
|
<< (8 * j);
|
||||||
|
|
||||||
/***************************test inode de/allocation**********************************/
|
assert(t == NUM_INODE_BLOCKS *
|
||||||
//when requesting an inode, the inode_allocation will give you the inode number, we use inode_list to store the sequence allocate inode
|
(IO_BLOCK_SIZE / INODE_SIZE)); // store the maximun th inode
|
||||||
//arrary version
|
|
||||||
int inode_list[20] = {0};
|
// test the end of inode
|
||||||
int record_free[10] = {0};//should do a pop up structure to record the free inode
|
t = 0;
|
||||||
int rec = 9;
|
for (int j = 0; j < 8; j++)
|
||||||
//printf("Allocate 20 inode num:{");
|
t |= ((u_int64_t)(unsigned char)buffer[j + IO_BLOCK_SIZE - INODE_SIZE])
|
||||||
for(int i=0;i<20;i++){
|
<< (8 * j);
|
||||||
inode_list[i] = inop.inode_allocate(*H);
|
|
||||||
assert(inode_list[i] == i+1);
|
assert(
|
||||||
//printf(" %d", inode_list[i]);
|
t ==
|
||||||
|
0); // the end of inode(524287th inode) do not have the next inode address
|
||||||
|
/**************************test datablock
|
||||||
|
* Initialization***************************/
|
||||||
|
// we separate 2048 4kB I/O block(1+2047) as a group and the first I/O block
|
||||||
|
// will manage the following 2047 I/O block usage. the first 8 bytes(0~7) in
|
||||||
|
// first I/O block store the address of next first I/O block, the following
|
||||||
|
// 256(8~263) bytes record 2047 I/O block usage. test the begining of free
|
||||||
|
// datablock
|
||||||
|
H->read_block(NUM_INODE_BLOCKS + 1,
|
||||||
|
buffer); // the begining of free datablock will store
|
||||||
|
// from address (MAX_INODE) * SECTOR_SIZE
|
||||||
|
t = 0;
|
||||||
|
for (int j = 0; j < 8; j++)
|
||||||
|
t |= ((u_int64_t)(unsigned char)buffer[j]) << (8 * j);
|
||||||
|
|
||||||
|
assert(t == NUM_INODE_BLOCKS + 1 + DATABLOCKS_PER_BITMAP_BLOCK +
|
||||||
|
1); // the first 8 bytes of 4k I/O block will store
|
||||||
|
// the next address(after 2048*4k I/O block)
|
||||||
|
// test the end of the datablock
|
||||||
|
H->read_block(NUM_BLOCKS - DATABLOCKS_PER_BITMAP_BLOCK - 1, buffer);
|
||||||
|
t = 0;
|
||||||
|
for (int j = 0; j < 8; j++)
|
||||||
|
t |= ((u_int64_t)(unsigned char)buffer[j]) << (8 * j);
|
||||||
|
|
||||||
|
assert(t == NUM_BLOCKS - DATABLOCKS_PER_BITMAP_BLOCK - 1);
|
||||||
|
|
||||||
|
/***************************test inode
|
||||||
|
* de/allocation**********************************/
|
||||||
|
// when requesting an inode, the inode_allocation will give you the inode
|
||||||
|
// number, we use inode_list to store the sequence allocate inode arrary
|
||||||
|
// version
|
||||||
|
INode_Data inode_list[20];
|
||||||
|
u_int64_t record_free[10] = {
|
||||||
|
0}; // should do a pop up structure to record the free inode
|
||||||
|
int rec = 9;
|
||||||
|
// printf("Allocate 20 inode num:{");
|
||||||
|
for (int i = 0; i < 20; i++) {
|
||||||
|
fs->inode_manager->new_inode(0, 0, 0, &inode_list[i]);
|
||||||
|
|
||||||
|
assert(inode_list[i].inode_num == i + 1);
|
||||||
|
// printf(" %d", inode_list[i].inode_num);
|
||||||
|
}
|
||||||
|
// printf("}\n");
|
||||||
|
for (int i = 10; i < 20; i++) {
|
||||||
|
record_free[i - 10] = inode_list[i].inode_num;
|
||||||
|
fs->inode_manager->free_inode(
|
||||||
|
&inode_list[i]); // free the 10 element from inode_list[10]
|
||||||
|
}
|
||||||
|
// allocate again the last 10
|
||||||
|
printf("Allocate again: inode num:{");
|
||||||
|
for (int i = 10; i < 20; i++) {
|
||||||
|
fs->inode_manager->new_inode(0, 0, 0, &inode_list[i]);
|
||||||
|
// printf("inode %d, rec_f %d\n,", inode_list[i],record_free[rec]);
|
||||||
|
assert(inode_list[i].inode_num == record_free[rec]);
|
||||||
|
rec--;
|
||||||
|
}
|
||||||
|
printf("}\n");
|
||||||
|
/***************************test direct blocks[48]
|
||||||
|
* de/allocation**********************************/
|
||||||
|
// after free the datablock, the program will find the first smallest address
|
||||||
|
// of datablock to give to the inode should test random resize each node, but
|
||||||
|
// should use datablock_free data structure to record
|
||||||
|
u_int64_t rec_datablock_free[10][3] = {0}; // array version
|
||||||
|
u_int64_t temp_block_num = 0;
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
// printf("%dth data block starting addres: ", i);
|
||||||
|
for (int j = 0; j < 6; j++) {
|
||||||
|
fs->allocate_datablock(&inode_list[i], &temp_block_num);
|
||||||
|
// printf("%d," ,inode_inside[i].datablock_allocate(*H));
|
||||||
}
|
}
|
||||||
//printf("}\n");
|
// printf("\n");
|
||||||
for(int i=10;i<20;i++){
|
}
|
||||||
inop.inode_free(*H,inode_list[i]);//free the 10 element from inode_list[10]
|
for (int i = 0; i < 10; i++) {
|
||||||
record_free[i-10] = inode_list[i];
|
// printf("%dth data block free addres: ", i);
|
||||||
}
|
for (int j = 2; j >= 0; j--) {
|
||||||
//allocate again the last 10
|
fs->deallocate_datablock(&inode_list[i], &(rec_datablock_free[i][j]));
|
||||||
printf("Allocate again: inode num:{");
|
// printf("", rec_datablock_free[i][j]);
|
||||||
for(int i=10;i<20;i++){
|
|
||||||
inode_list[i] = inop.inode_allocate(*H);
|
|
||||||
//printf("inode %d, rec_f %d\n,", inode_list[i],record_free[rec]);
|
|
||||||
assert(inode_list[i] == record_free[rec]);
|
|
||||||
rec--;
|
|
||||||
}
|
|
||||||
printf("}\n");
|
|
||||||
/***************************test direct blocks[48] de/allocation**********************************/
|
|
||||||
//after free the datablock, the program will find the first smallest address of datablock to give to the inode
|
|
||||||
//should test random resize each node, but should use datablock_free data structure to record
|
|
||||||
INode inode_inside[10];
|
|
||||||
u_int64_t rec_datablock_free[10][3] = {0};//array version
|
|
||||||
for(int i=0;i<10;i++){
|
|
||||||
inode_inside[i].inode_construct(inode_list[i],*H);
|
|
||||||
//printf("%dth data block starting addres: ", i);
|
|
||||||
for(int j=0;j<6;j++){
|
|
||||||
inode_inside[i].datablock_allocate(*H);
|
|
||||||
//printf("%d," ,inode_inside[i].datablock_allocate(*H));
|
|
||||||
}
|
|
||||||
//printf("\n");
|
|
||||||
}
|
|
||||||
for(int i=0;i<10;i++){
|
|
||||||
//printf("%dth data block free addres: ", i);
|
|
||||||
for(int j = 2;j >=0;j--){
|
|
||||||
rec_datablock_free[i][j] = inode_inside[i].datablock_deallocate(*H);
|
|
||||||
//printf("", rec_datablock_free[i][j]);
|
|
||||||
}
|
|
||||||
//printf("\n");
|
|
||||||
}
|
}
|
||||||
|
// printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
for(int i=0;i<10;i++){
|
for (int i = 0; i < 10; i++) {
|
||||||
//printf("%dth data block allocate again addres: ", i);
|
// printf("%dth data block allocate again addres: ", i);
|
||||||
for(int j=0;j<3;j++){
|
for (int j = 0; j < 3; j++) {
|
||||||
assert(inode_inside[i].datablock_allocate(*H) == rec_datablock_free[i][j]);
|
fs->allocate_datablock(&inode_list[i], &temp_block_num);
|
||||||
//printf("%d," ,inode_inside[i].datablock_allocate(*H));
|
assert(temp_block_num == rec_datablock_free[i][j]);
|
||||||
}
|
// printf("%d," ,inode_inside[i].datablock_allocate(*H));
|
||||||
//printf("\n");
|
|
||||||
}
|
}
|
||||||
|
// printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
//printf("}\n");
|
// printf("}\n");
|
||||||
delete H; // Delete the RawDisk object
|
delete H; // Delete the RawDisk object
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,113 +1,130 @@
|
|||||||
#include <stdio.h>
|
// #include "fs.h"
|
||||||
#include <string.h>
|
// #include <assert.h>
|
||||||
#include <assert.h>
|
// #include <inttypes.h>
|
||||||
#include "fs.h"
|
// #include <stdio.h>
|
||||||
#include <inttypes.h>
|
// #include <string.h>
|
||||||
|
|
||||||
// in fs.h:
|
// // in fs.h:
|
||||||
// #define MAX_INODE 2048
|
// // #define MAX_INODE 2048
|
||||||
// #define MAX_BLOCKNUM 51200
|
// // #define MAX_BLOCKNUM 51200
|
||||||
// 51200 Sectors = 2048 * 25 Sectors = 25MB
|
// // 51200 Sectors = 2048 * 25 Sectors = 25MB
|
||||||
// Free List Heads: 2048*512, 2048*9*512, 2048*17*512
|
// // Free List Heads: 2048*512, 2048*9*512, 2048*17*512
|
||||||
// Available INodes: 2047 (-1 because superblock)
|
// // Available INodes: 2047 (-1 because superblock)
|
||||||
// Available DataBlocks (including Indirect Blocks): 2047 * 3 = 6141
|
// // Available DataBlocks (including Indirect Blocks): 2047 * 3 = 6141
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
// int main(int argc, char *argv[]) {
|
||||||
const char* d = (argc < 2) ? "/dev/vdc" : argv[1];
|
// const char *d = (argc < 2) ? "/dev/vdc" : argv[1];
|
||||||
|
|
||||||
RawDisk *H = new RawDisk(d);
|
// RawDisk *H = new FakeRawDisk(d);
|
||||||
|
|
||||||
printf("=== INode Alloc/Dealloc Test ===\n");
|
// printf("=== INode Alloc/Dealloc Test ===\n");
|
||||||
INodeOperation inop;
|
// INodeOperation inop;
|
||||||
inop.initialize(*H);
|
// inop.initialize(*H);
|
||||||
|
|
||||||
// Test INode alloc and dealloc
|
// // Test INode alloc and dealloc
|
||||||
int inode_list[2046] = {0}; // if we allocate 2047 inodes head will be 0 (faulty)
|
// int inode_list[2046] = {
|
||||||
printf("freeInodeHead: %d \n", SuperBlock::getFreeINodeHead(*H)); // this impl should give 1
|
// 0}; // if we allocate 2047 inodes head will be 0 (faulty)
|
||||||
for(int i=0;i<2046;i++){
|
// printf("freeInodeHead: %d \n",
|
||||||
inode_list[i] = inop.inode_allocate(*H);
|
// SuperBlock::getFreeINodeHead(*H)); // this impl should give 1
|
||||||
if (SuperBlock::getFreeINodeHead(*H) == 0) {
|
// for (int i = 0; i < 2046; i++) {
|
||||||
printf("%d\n",i);
|
// inode_list[i] = inop.inode_allocate(*H);
|
||||||
assert(false);
|
// if (SuperBlock::getFreeINodeHead(*H) == 0) {
|
||||||
}
|
// printf("%d\n", i);
|
||||||
}
|
// assert(false);
|
||||||
printf("freeInodeHead: %d \n", SuperBlock::getFreeINodeHead(*H)); // this impl should give 2047
|
// }
|
||||||
for(int i=0;i<1024;i++){
|
// }
|
||||||
inop.inode_free(*H,inode_list[i]);
|
// printf("freeInodeHead: %d \n",
|
||||||
}
|
// SuperBlock::getFreeINodeHead(*H)); // this impl should give 2047
|
||||||
for(int i=0;i<1022;i++){
|
// for (int i = 0; i < 1024; i++) {
|
||||||
inode_list[i] = inop.inode_allocate(*H);
|
// inop.inode_free(*H, inode_list[i]);
|
||||||
assert(SuperBlock::getFreeINodeHead(*H) != 0);
|
// }
|
||||||
}
|
// for (int i = 0; i < 1022; i++) {
|
||||||
printf("freeInodeHead: %d \n", SuperBlock::getFreeINodeHead(*H)); // this impl should give 2
|
// inode_list[i] = inop.inode_allocate(*H);
|
||||||
inode_list[1022] = inop.inode_allocate(*H);
|
// assert(SuperBlock::getFreeINodeHead(*H) != 0);
|
||||||
printf("freeInodeHead: %d \n", SuperBlock::getFreeINodeHead(*H)); // this impl should give 1
|
// }
|
||||||
inode_list[1023] = inop.inode_allocate(*H);
|
// printf("freeInodeHead: %d \n",
|
||||||
printf("freeInodeHead: %d \n", SuperBlock::getFreeINodeHead(*H)); // this impl should give 2047
|
// SuperBlock::getFreeINodeHead(*H)); // this impl should give 2
|
||||||
|
// inode_list[1022] = inop.inode_allocate(*H);
|
||||||
// Test Many Files
|
// printf("freeInodeHead: %d \n",
|
||||||
printf("=== Many Files Test ===\n");
|
// SuperBlock::getFreeINodeHead(*H)); // this impl should give 1
|
||||||
INode inode_inside[100];
|
// inode_list[1023] = inop.inode_allocate(*H);
|
||||||
for(int i=0;i<100;i++){
|
// printf("freeInodeHead: %d \n",
|
||||||
inode_inside[i].inode_construct(inode_list[i],*H);
|
// SuperBlock::getFreeINodeHead(*H)); // this impl should give 2047
|
||||||
for(int j=0;j<60;j++) { // Note that 1 indirect block is used for each file
|
|
||||||
u_int64_t allcBlockNum = inode_inside[i].datablock_allocate(*H);
|
// // Test Many Files
|
||||||
if (SuperBlock::getFreeListHead(*H) >= (u_int64_t) 51200*512) {
|
// printf("=== Many Files Test ===\n");
|
||||||
printf("Bad FreeListHead: %d, %d, %llu\n", i, j, SuperBlock::getFreeListHead(*H));
|
// INode inode_inside[100];
|
||||||
assert(false);
|
// for (int i = 0; i < 100; i++) {
|
||||||
}
|
// inode_inside[i].inode_construct(inode_list[i], *H);
|
||||||
if (allcBlockNum % 2048 != 0 || allcBlockNum < 2048*512 || allcBlockNum >= 25*2048*512) {
|
// for (int j = 0; j < 60;
|
||||||
printf("Bad Allocated Block Number: %d, %d, %llu\n", i, j, allcBlockNum);
|
// j++) { // Note that 1 indirect block is used for each file
|
||||||
assert(false);
|
// u_int64_t allcBlockNum = inode_inside[i].datablock_allocate(*H);
|
||||||
}
|
// if (SuperBlock::getFreeListHead(*H) >= (u_int64_t)51200 * 512) {
|
||||||
}
|
// printf("Bad FreeListHead: %d, %d, %llu\n", i, j,
|
||||||
}
|
// SuperBlock::getFreeListHead(*H));
|
||||||
printf("Finished Allocating\n");
|
// assert(false);
|
||||||
// in this impl should give 17*2048*512 = 17825792
|
// }
|
||||||
printf("freeListHead: %llu \n", SuperBlock::getFreeListHead(*H)); // if all 6141 blocks allocated, would give 51200*512 (faulty)
|
// if (allcBlockNum % 2048 != 0 || allcBlockNum < 2048 * 512 ||
|
||||||
for(int i=0;i<100;i++){
|
// allcBlockNum >= 25 * 2048 * 512) {
|
||||||
for(int j=0;j<59;j++){
|
// printf("Bad Allocated Block Number: %d, %d, %llu\n", i, j,
|
||||||
u_int64_t freedBlkNum = inode_inside[i].datablock_deallocate(*H);
|
// allcBlockNum);
|
||||||
u_int64_t fh = SuperBlock::getFreeListHead(*H);
|
// assert(false);
|
||||||
if (freedBlkNum % 2048 != 0 || freedBlkNum < 2048*512 || freedBlkNum >= 25*2048*512 || fh >= 51200*512) {
|
// }
|
||||||
printf("%d, %d, Freed Block Number: %llu\n", i, j, freedBlkNum);
|
// }
|
||||||
printf("FreeListHead is %llu\n", fh);
|
// }
|
||||||
assert(false);
|
// printf("Finished Allocating\n");
|
||||||
}
|
// // in this impl should give 17*2048*512 = 17825792
|
||||||
}
|
// printf(
|
||||||
}
|
// "freeListHead: %llu \n",
|
||||||
printf("Finished Deallocating\n");
|
// SuperBlock::getFreeListHead(
|
||||||
printf("freeListHead: %d \n", SuperBlock::getFreeListHead(*H));
|
// *H)); // if all 6141 blocks allocated, would give 51200*512
|
||||||
|
// (faulty)
|
||||||
// Test Big File (Use direct, single indirect, double indirect)
|
// for (int i = 0; i < 100; i++) {
|
||||||
printf("=== Big File Test ===\n");
|
// for (int j = 0; j < 59; j++) {
|
||||||
u_int64_t lastAllc = 0;
|
// u_int64_t freedBlkNum = inode_inside[i].datablock_deallocate(*H);
|
||||||
for(int j=0;j<5000;j++){
|
// u_int64_t fh = SuperBlock::getFreeListHead(*H);
|
||||||
u_int64_t allcBlockNum = inode_inside[0].datablock_allocate(*H);
|
// if (freedBlkNum % 2048 != 0 || freedBlkNum < 2048 * 512 ||
|
||||||
lastAllc = allcBlockNum;
|
// freedBlkNum >= 25 * 2048 * 512 || fh >= 51200 * 512) {
|
||||||
u_int64_t fh = SuperBlock::getFreeListHead(*H);
|
// printf("%d, %d, Freed Block Number: %llu\n", i, j, freedBlkNum);
|
||||||
if (allcBlockNum % 2048 != 0 || allcBlockNum < 2048*512 || allcBlockNum >= 25*2048*512 || fh >= 51200*512) {
|
// printf("FreeListHead is %llu\n", fh);
|
||||||
printf("%d, Alloc Block Number: %llu\n", j, allcBlockNum);
|
// assert(false);
|
||||||
printf("FreeListHead is %llu\n", fh);
|
// }
|
||||||
assert(false);
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// printf("Finished Deallocating\n");
|
||||||
printf("last allocate for big file: %llu\n", lastAllc);
|
// printf("freeListHead: %d \n", SuperBlock::getFreeListHead(*H));
|
||||||
printf("Finished Allocating\n");
|
|
||||||
printf("freeListHead: %d \n", SuperBlock::getFreeListHead(*H));
|
// // Test Big File (Use direct, single indirect, double indirect)
|
||||||
for(int j=0;j<5000;j++){
|
// printf("=== Big File Test ===\n");
|
||||||
u_int64_t freedBlkNum = inode_inside[0].datablock_deallocate(*H);
|
// u_int64_t lastAllc = 0;
|
||||||
u_int64_t fh = SuperBlock::getFreeListHead(*H);
|
// for (int j = 0; j < 5000; j++) {
|
||||||
if (freedBlkNum % 2048 != 0 || freedBlkNum < 2048*512 || freedBlkNum >= 25*2048*512 || fh >= 51200*512) {
|
// u_int64_t allcBlockNum = inode_inside[0].datablock_allocate(*H);
|
||||||
printf("%d, Freed Block Number: %llu\n", j, freedBlkNum);
|
// lastAllc = allcBlockNum;
|
||||||
printf("FreeListHead is %llu\n", fh);
|
// u_int64_t fh = SuperBlock::getFreeListHead(*H);
|
||||||
assert(false);
|
// if (allcBlockNum % 2048 != 0 || allcBlockNum < 2048 * 512 ||
|
||||||
}
|
// allcBlockNum >= 25 * 2048 * 512 || fh >= 51200 * 512) {
|
||||||
}
|
// printf("%d, Alloc Block Number: %llu\n", j, allcBlockNum);
|
||||||
printf("Finished Deallocating\n");
|
// printf("FreeListHead is %llu\n", fh);
|
||||||
printf("freeListHead: %d \n", SuperBlock::getFreeListHead(*H));
|
// assert(false);
|
||||||
|
// }
|
||||||
delete H; // Delete the RawDisk object
|
// }
|
||||||
|
// printf("last allocate for big file: %llu\n", lastAllc);
|
||||||
return 0;
|
// printf("Finished Allocating\n");
|
||||||
}
|
// printf("freeListHead: %d \n", SuperBlock::getFreeListHead(*H));
|
||||||
|
// for (int j = 0; j < 5000; j++) {
|
||||||
|
// u_int64_t freedBlkNum = inode_inside[0].datablock_deallocate(*H);
|
||||||
|
// u_int64_t fh = SuperBlock::getFreeListHead(*H);
|
||||||
|
// if (freedBlkNum % 2048 != 0 || freedBlkNum < 2048 * 512 ||
|
||||||
|
// freedBlkNum >= 25 * 2048 * 512 || fh >= 51200 * 512) {
|
||||||
|
// printf("%d, Freed Block Number: %llu\n", j, freedBlkNum);
|
||||||
|
// printf("FreeListHead is %llu\n", fh);
|
||||||
|
// assert(false);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// printf("Finished Deallocating\n");
|
||||||
|
// printf("freeListHead: %d \n", SuperBlock::getFreeListHead(*H));
|
||||||
|
|
||||||
|
// delete H; // Delete the RawDisk object
|
||||||
|
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user