modify layer 1 for pressure testing on a small fs
This commit is contained in:
parent
1d567ff487
commit
47927b0a8a
32
include/fs.h
32
include/fs.h
@ -9,8 +9,10 @@ one inode equipped with one 512 bytes block
|
|||||||
*****************************************************/
|
*****************************************************/
|
||||||
#define SECTOR_SIZE 512
|
#define SECTOR_SIZE 512
|
||||||
#define IO_BLOCK_SIZE 4096
|
#define IO_BLOCK_SIZE 4096
|
||||||
#define MAX_INODE 524288
|
#define MAX_INODE 2048
|
||||||
#define MAX_BLOCKNUM MAX_INODE*2 //62914560
|
// 524288
|
||||||
|
#define MAX_BLOCKNUM 51200
|
||||||
|
// 1GB Disk: 2097152 = 196512 IO_BLOCK's. MAX_INODE*2 //62914560
|
||||||
|
|
||||||
class SuperBlock{
|
class SuperBlock{
|
||||||
|
|
||||||
@ -159,6 +161,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// we can assert here that freeBlockNum is nonzero here, since we always change head when a block is full (see below)
|
||||||
disk.rawdisk_write(freeListHead, buffer, sizeof(buffer));
|
disk.rawdisk_write(freeListHead, buffer, sizeof(buffer));
|
||||||
bool notFull = false;
|
bool notFull = false;
|
||||||
for (int i = 8; i < 264; i++){
|
for (int i = 8; i < 264; i++){
|
||||||
@ -168,8 +171,8 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!notFull){
|
if (!notFull){
|
||||||
printf("HEADER REMOVAL DETECTED %llu %llu\n", freeListHead, freeBlockNum);
|
|
||||||
u_int64_t next_header = read_byte_at(0, buffer);
|
u_int64_t next_header = read_byte_at(0, buffer);
|
||||||
|
printf("HEADER MOVE (Cause: Alloc) %llu -> %llu (%llu)\n", freeListHead, next_header, freeBlockNum);
|
||||||
SuperBlock::writeFreeListHead(disk, next_header);
|
SuperBlock::writeFreeListHead(disk, next_header);
|
||||||
}
|
}
|
||||||
return freeBlockNum;
|
return freeBlockNum;
|
||||||
@ -178,6 +181,9 @@ public:
|
|||||||
bool allo_single_indirect(RawDisk &disk, u_int64_t &single_i, u_int64_t freeBlockNum) {
|
bool allo_single_indirect(RawDisk &disk, u_int64_t &single_i, u_int64_t freeBlockNum) {
|
||||||
if (single_i == 0){
|
if (single_i == 0){
|
||||||
single_i = datablock_allocate_in_list(disk);
|
single_i = datablock_allocate_in_list(disk);
|
||||||
|
char init_buffer[IO_BLOCK_SIZE] = {0};
|
||||||
|
disk.rawdisk_write(single_i, init_buffer, sizeof(init_buffer));
|
||||||
|
// I think the same should be done to alloc double, triple indirect
|
||||||
}
|
}
|
||||||
bool inSingle = false;
|
bool inSingle = false;
|
||||||
char buffer[IO_BLOCK_SIZE] = {0};
|
char buffer[IO_BLOCK_SIZE] = {0};
|
||||||
@ -197,6 +203,8 @@ public:
|
|||||||
bool allo_double_indirect(RawDisk &disk, u_int64_t &double_i, u_int64_t freeBlockNum) {
|
bool allo_double_indirect(RawDisk &disk, u_int64_t &double_i, u_int64_t freeBlockNum) {
|
||||||
if (double_i == 0){
|
if (double_i == 0){
|
||||||
double_i = datablock_allocate_in_list(disk);
|
double_i = datablock_allocate_in_list(disk);
|
||||||
|
char init_buffer[IO_BLOCK_SIZE] = {0};
|
||||||
|
disk.rawdisk_write(double_i, init_buffer, sizeof(init_buffer));
|
||||||
}
|
}
|
||||||
bool inDouble = false;
|
bool inDouble = false;
|
||||||
char buffer[IO_BLOCK_SIZE] = {0};
|
char buffer[IO_BLOCK_SIZE] = {0};
|
||||||
@ -217,6 +225,8 @@ public:
|
|||||||
bool allo_triple_indirect(RawDisk &disk, u_int64_t &triple_i, u_int64_t freeBlockNum) {
|
bool allo_triple_indirect(RawDisk &disk, u_int64_t &triple_i, u_int64_t freeBlockNum) {
|
||||||
if (triple_i == 0){
|
if (triple_i == 0){
|
||||||
triple_i = datablock_allocate_in_list(disk);
|
triple_i = datablock_allocate_in_list(disk);
|
||||||
|
char init_buffer[IO_BLOCK_SIZE] = {0};
|
||||||
|
disk.rawdisk_write(triple_i, init_buffer, sizeof(init_buffer));
|
||||||
}
|
}
|
||||||
bool inTriple = false;
|
bool inTriple = false;
|
||||||
char buffer[IO_BLOCK_SIZE] = {0};
|
char buffer[IO_BLOCK_SIZE] = {0};
|
||||||
@ -268,22 +278,25 @@ public:
|
|||||||
// find the related 2048block head
|
// find the related 2048block head
|
||||||
u_int64_t freeBlockHead = ((freeBlockNum/SECTOR_SIZE-MAX_INODE)/(8*2048)*(8*2048)+MAX_INODE)*SECTOR_SIZE;
|
u_int64_t freeBlockHead = ((freeBlockNum/SECTOR_SIZE-MAX_INODE)/(8*2048)*(8*2048)+MAX_INODE)*SECTOR_SIZE;
|
||||||
|
|
||||||
// mark it alive in its bitmap
|
|
||||||
char buffer[IO_BLOCK_SIZE] = {0};
|
char buffer[IO_BLOCK_SIZE] = {0};
|
||||||
bool notEmpty = false;
|
|
||||||
disk.rawdisk_read(freeBlockHead, buffer, sizeof(buffer));
|
disk.rawdisk_read(freeBlockHead, buffer, sizeof(buffer));
|
||||||
|
|
||||||
|
// mark it alive in its bitmap
|
||||||
|
u_int64_t inBlockPos = (freeBlockNum-freeBlockHead)/IO_BLOCK_SIZE-1;
|
||||||
|
buffer[8+inBlockPos/8] &= (-1)^(1<<(inBlockPos%8));
|
||||||
|
|
||||||
|
bool notEmpty = false;
|
||||||
for (int i = 8; i < 264; i++){
|
for (int i = 8; i < 264; i++){
|
||||||
if(buffer[i] != 0){
|
if(buffer[i] != 0){
|
||||||
notEmpty = true;
|
notEmpty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
u_int64_t inBlockPos = (freeBlockNum-freeBlockHead)/IO_BLOCK_SIZE-1;
|
|
||||||
buffer[8+inBlockPos/8] &= (-1)^(1<<(inBlockPos%8));
|
|
||||||
|
|
||||||
// if its bitmap was 0, add it back to the list head
|
// if its bitmap was 0, add it back to the list head
|
||||||
if(!notEmpty){
|
if(!notEmpty){
|
||||||
u_int64_t freeListHead = SuperBlock::getFreeListHead(disk);
|
u_int64_t freeListHead = SuperBlock::getFreeListHead(disk);
|
||||||
write_byte_at(freeListHead, 0, buffer);
|
write_byte_at(freeListHead, 0, buffer);
|
||||||
|
printf("HEADER MOVE (Cause: Dealloc) %llu -> %llu\n", freeListHead, freeBlockHead);
|
||||||
SuperBlock::writeFreeListHead(disk, freeBlockHead);
|
SuperBlock::writeFreeListHead(disk, freeBlockHead);
|
||||||
}
|
}
|
||||||
disk.rawdisk_write(freeBlockHead, buffer, sizeof(buffer));
|
disk.rawdisk_write(freeBlockHead, buffer, sizeof(buffer));
|
||||||
@ -297,13 +310,14 @@ public:
|
|||||||
char buffer[IO_BLOCK_SIZE] = {0};
|
char buffer[IO_BLOCK_SIZE] = {0};
|
||||||
int delpoint = -1;
|
int delpoint = -1;
|
||||||
disk.rawdisk_read(single_i, buffer, sizeof(buffer));
|
disk.rawdisk_read(single_i, buffer, sizeof(buffer));
|
||||||
for (int i=4088; i >= 0; i--){
|
for (int i=4088; i >= 0; i-=8){
|
||||||
u_int64_t addr = read_byte_at(i, buffer);
|
u_int64_t addr = read_byte_at(i, buffer);
|
||||||
if(addr != 0){
|
if(addr != 0){
|
||||||
freeBlockNum = addr;
|
freeBlockNum = addr;
|
||||||
addr = 0;
|
addr = 0;
|
||||||
write_byte_at(addr, i, buffer);
|
write_byte_at(addr, i, buffer);
|
||||||
delpoint = i;
|
delpoint = i;
|
||||||
|
//printf("delpoint: %d\n", delpoint);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -377,8 +391,10 @@ public:
|
|||||||
freeBlockNum = deallo_triple_indirect(disk, triple_indirect);
|
freeBlockNum = deallo_triple_indirect(disk, triple_indirect);
|
||||||
if(!freeBlockNum){
|
if(!freeBlockNum){
|
||||||
freeBlockNum = deallo_double_indirect(disk, double_indirect);
|
freeBlockNum = deallo_double_indirect(disk, double_indirect);
|
||||||
|
//printf("In fs.h, Inode::datablock_deallocate: finished dealloc double indirect, got %lld\n", freeBlockNum);
|
||||||
if(!freeBlockNum){
|
if(!freeBlockNum){
|
||||||
freeBlockNum = deallo_single_indirect(disk, single_indirect);
|
freeBlockNum = deallo_single_indirect(disk, single_indirect);
|
||||||
|
//printf("In fs.h, Inode::datablock_deallocate: finished dealloc single indirect, got %lld\n", freeBlockNum);
|
||||||
if(!freeBlockNum){
|
if(!freeBlockNum){
|
||||||
for(int i = 47; i>=0; i--)
|
for(int i = 47; i>=0; i--)
|
||||||
if(blocks[i] != 0){
|
if(blocks[i] != 0){
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
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(DIR_PLACE /dev/vdb)
|
set(DIR_PLACE /dev/vdb)
|
||||||
|
|
||||||
# add test sources here ...
|
# add test sources here ...
|
||||||
@ -11,7 +12,12 @@ 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
|
||||||
)
|
)
|
||||||
|
add_executable(${TARGET_LAYER1_TEST1}
|
||||||
|
# add need lib and source code here
|
||||||
|
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})
|
110
test/layer1_test1.cpp
Normal file
110
test/layer1_test1.cpp
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include "fs.h"
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
// in fs.h:
|
||||||
|
// #define MAX_INODE 2048
|
||||||
|
// #define MAX_BLOCKNUM 51200
|
||||||
|
// 51200 Sectors = 2048 * 25 Sectors = 25MB
|
||||||
|
// Free List Heads: 2048*512, 2048*9*512, 2048*17*512
|
||||||
|
// Available INodes: 2047 (-1 because superblock)
|
||||||
|
// Available DataBlocks (including Indirect Blocks): 2047 * 3 = 6141
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
const char* d = (argc < 2) ? "/dev/vdc" : argv[1];
|
||||||
|
|
||||||
|
RawDisk *H = new RawDisk(d);
|
||||||
|
|
||||||
|
printf("=== INode Alloc/Dealloc Test ===\n");
|
||||||
|
INodeOperation inop;
|
||||||
|
inop.initialize(*H);
|
||||||
|
|
||||||
|
// Test INode alloc and dealloc
|
||||||
|
int inode_list[2046] = {0}; // if we allocate 2047 inodes head will be 0 (faulty)
|
||||||
|
printf("freeInodeHead: %d \n", SuperBlock::getFreeINodeHead(*H)); // this impl should give 1
|
||||||
|
for(int i=0;i<2046;i++){
|
||||||
|
inode_list[i] = inop.inode_allocate(*H);
|
||||||
|
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]);
|
||||||
|
}
|
||||||
|
for(int i=0;i<1022;i++){
|
||||||
|
inode_list[i] = inop.inode_allocate(*H);
|
||||||
|
assert(SuperBlock::getFreeINodeHead(*H) != 0);
|
||||||
|
}
|
||||||
|
printf("freeInodeHead: %d \n", SuperBlock::getFreeINodeHead(*H)); // this impl should give 2
|
||||||
|
inode_list[1022] = inop.inode_allocate(*H);
|
||||||
|
printf("freeInodeHead: %d \n", SuperBlock::getFreeINodeHead(*H)); // this impl should give 1
|
||||||
|
inode_list[1023] = inop.inode_allocate(*H);
|
||||||
|
printf("freeInodeHead: %d \n", SuperBlock::getFreeINodeHead(*H)); // this impl should give 2047
|
||||||
|
|
||||||
|
// Test Many Files
|
||||||
|
printf("=== Many Files Test ===\n");
|
||||||
|
INode inode_inside[100];
|
||||||
|
for(int i=0;i<100;i++){
|
||||||
|
inode_inside[i].inode_construct(inode_list[i],*H);
|
||||||
|
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);
|
||||||
|
if (SuperBlock::getFreeListHead(*H) >= (u_int64_t) 51200*512) {
|
||||||
|
printf("Bad FreeListHead: %d, %d, %llu\n", i, j, SuperBlock::getFreeListHead(*H));
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
if (allcBlockNum % 2048 != 0 || allcBlockNum < 2048*512 || allcBlockNum >= 25*2048*512) {
|
||||||
|
printf("Bad Allocated Block Number: %d, %d, %llu\n", i, j, allcBlockNum);
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("Finished Allocating\n");
|
||||||
|
// 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)
|
||||||
|
for(int i=0;i<100;i++){
|
||||||
|
for(int j=0;j<59;j++){
|
||||||
|
u_int64_t freedBlkNum = inode_inside[i].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, %d, Freed Block Number: %llu\n", i, j, freedBlkNum);
|
||||||
|
printf("FreeListHead is %llu\n", fh);
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("Finished Deallocating\n");
|
||||||
|
printf("freeListHead: %d \n", SuperBlock::getFreeListHead(*H));
|
||||||
|
|
||||||
|
// Test Big File (Use direct, single indirect, double indirect)
|
||||||
|
printf("=== Big File Test ===\n");
|
||||||
|
for(int j=0;j<5000;j++){
|
||||||
|
u_int64_t allcBlockNum = inode_inside[0].datablock_allocate(*H);
|
||||||
|
u_int64_t fh = SuperBlock::getFreeListHead(*H);
|
||||||
|
if (allcBlockNum % 2048 != 0 || allcBlockNum < 2048*512 || allcBlockNum >= 25*2048*512 || fh >= 51200*512) {
|
||||||
|
printf("%d, Alloc Block Number: %llu\n", j, allcBlockNum);
|
||||||
|
printf("FreeListHead is %llu\n", fh);
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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