temporary addition of new header structure
This commit is contained in:
parent
493b064e48
commit
85bf159ee0
14
.gitignore
vendored
14
.gitignore
vendored
@ -1 +1,15 @@
|
||||
build/*
|
||||
|
||||
# vscode gitignore
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
!.vscode/*.code-snippets
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
6
.vscode/settings.json
vendored
Normal file
6
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"cmake.configureOnOpen": false,
|
||||
"cSpell.words": [
|
||||
"unneccary"
|
||||
]
|
||||
}
|
@ -13,6 +13,9 @@ add_executable(fischl
|
||||
# Header files
|
||||
lib/fischl.cpp
|
||||
lib/main.cpp
|
||||
lib/fs/fs_data_types.cpp
|
||||
lib/fs/fs_resize.cpp
|
||||
lib/fs/fs.cpp
|
||||
|
||||
)
|
||||
|
||||
|
63
Issues.txt
Normal file
63
Issues.txt
Normal file
@ -0,0 +1,63 @@
|
||||
Problem - no header guards
|
||||
Problem - code in header file
|
||||
Problem - inconisitent use of SECTOR_SIZE IO_BLOCK_SIZE
|
||||
|
||||
|
||||
?18: what is directory
|
||||
|
||||
22: read of less than sector-size unpermitted
|
||||
|
||||
?25: does the casting here work as expected, would a bitmask be better
|
||||
|
||||
Question: why are we passing a disk every time to superblock functions, shouldn't that be associated with the superblock (i.e. the file system object)
|
||||
|
||||
37: same issues with this function
|
||||
|
||||
Superblock should be read and written to all at once to avoid unneccary io reads and should be stateful regarding the fs data (also it maybe good to rename superblock to fs and make it in charge of formatting the fs)
|
||||
|
||||
57: magic num
|
||||
|
||||
?69: strange reference pattern with current_pos - usually handled by func returning num bytes read
|
||||
|
||||
?69: should these helper functions be in the inode at all
|
||||
|
||||
?76: these two funcs could be combined together
|
||||
|
||||
?83: inode_construct may want to be named inode_load to fit pattern
|
||||
|
||||
inode objs (block_number) should likely be able to be made with out the use of inode_construct when they are first created
|
||||
|
||||
|
||||
132:
|
||||
|
||||
?142: odd use of block nums - byte addresses and io_block addresses
|
||||
|
||||
143: magic num 32?
|
||||
|
||||
?144: possibly make this a continue also use 0b11111111 and 0b01111111
|
||||
|
||||
?145: j = 0 twice
|
||||
|
||||
?76: why is this function read_byte_at if it reads 8 bytes
|
||||
|
||||
?144: why is the last bit of the bitmask unused
|
||||
|
||||
?171: returned free must be zeroed before use
|
||||
|
||||
177: no error handling for cannot allocate block (free list empty)
|
||||
|
||||
?215: should this be made into a recursive func
|
||||
|
||||
241: no error checking
|
||||
|
||||
278: the empty checking and adding to free list head seems busted
|
||||
|
||||
303: --
|
||||
|
||||
?315: && addr == 0 does nothing
|
||||
|
||||
398: can try to deallocate the super block so // deal with empty needs implementation
|
||||
|
||||
?433: why even mix sector size into free list
|
||||
|
||||
428: no limit checking
|
258
include/fs.h
258
include/fs.h
@ -1,8 +1,8 @@
|
||||
#include "rawdisk.h"
|
||||
/*****************************************************
|
||||
30GB Disk low-level operation and data structure: spuerblock, inode, and buffer cache
|
||||
512 bytes sector for 1 block, 62914560 block(sector)
|
||||
4K bytes sector for 1 block, 7864320 block(sector)
|
||||
30GB Disk low-level operation and data structure: spuerblock, inode, and buffer
|
||||
cache 512 bytes sector for 1 block, 62914560 block(sector) 4K bytes sector for 1
|
||||
block, 7864320 block(sector)
|
||||
|
||||
one inode equipped with one 512 bytes block
|
||||
|
||||
@ -10,53 +10,49 @@ one inode equipped with one 512 bytes block
|
||||
#define SECTOR_SIZE 512
|
||||
#define IO_BLOCK_SIZE 4096
|
||||
#define MAX_INODE 524288
|
||||
#define MAX_BLOCKNUM MAX_INODE*2 //62914560
|
||||
#define MAX_BLOCKNUM MAX_INODE * 2 // 62914560
|
||||
|
||||
class SuperBlock{
|
||||
class SuperBlock {
|
||||
|
||||
public:
|
||||
SuperBlock(const char *directory){
|
||||
|
||||
}
|
||||
~SuperBlock(){
|
||||
|
||||
}
|
||||
static u_int64_t getFreeListHead(RawDisk &disk){
|
||||
SuperBlock(const char *directory) {}
|
||||
~SuperBlock() {}
|
||||
static u_int64_t getFreeListHead(RawDisk &disk) {
|
||||
char buffer[8] = {0};
|
||||
disk.rawdisk_read(0, buffer, sizeof(buffer));
|
||||
u_int64_t t = 0;
|
||||
for (int j = 0; j < 8; j++)
|
||||
t = t | (((u_int64_t)(unsigned char)buffer[j])<<(8*j));
|
||||
t = t | (((u_int64_t)(unsigned char)buffer[j]) << (8 * j));
|
||||
return t;
|
||||
}
|
||||
|
||||
static void writeFreeListHead(RawDisk &disk, u_int64_t t){
|
||||
static void writeFreeListHead(RawDisk &disk, u_int64_t t) {
|
||||
char buffer[8] = {0};
|
||||
for (int j = 0; j < 8; j++){
|
||||
for (int j = 0; j < 8; j++) {
|
||||
buffer[j] = (t >> (8 * j)) & 0xFF;
|
||||
}
|
||||
disk.rawdisk_write(0, buffer, sizeof(buffer));
|
||||
}
|
||||
|
||||
static u_int64_t getFreeINodeHead(RawDisk &disk){
|
||||
static u_int64_t getFreeINodeHead(RawDisk &disk) {
|
||||
char buffer[8] = {0};
|
||||
disk.rawdisk_read(8, buffer, sizeof(buffer));
|
||||
u_int64_t t = 0;
|
||||
for (int j = 0; j < 8; j++)
|
||||
t = t | (((u_int64_t)(unsigned char)buffer[j])<<(8*j));
|
||||
t = t | (((u_int64_t)(unsigned char)buffer[j]) << (8 * j));
|
||||
return t;
|
||||
}
|
||||
|
||||
static void writeFreeINodeHead(RawDisk &disk, u_int64_t t){
|
||||
static void writeFreeINodeHead(RawDisk &disk, u_int64_t t) {
|
||||
char buffer[8] = {0};
|
||||
for (int j = 0; j < 8; j++){
|
||||
for (int j = 0; j < 8; j++) {
|
||||
buffer[j] = (t >> (8 * j)) & 0xFF;
|
||||
}
|
||||
disk.rawdisk_write(8, buffer, sizeof(buffer));
|
||||
}
|
||||
};
|
||||
|
||||
class INode{
|
||||
class INode {
|
||||
// direct datablocks
|
||||
u_int64_t blocks[48];
|
||||
// indirect address
|
||||
@ -70,27 +66,27 @@ class INode{
|
||||
u_int64_t block_number;
|
||||
|
||||
public:
|
||||
void read_get_byte(u_int64_t &t, int ¤t_pos, char *buffer){
|
||||
void read_get_byte(u_int64_t &t, int ¤t_pos, char *buffer) {
|
||||
t = 0;
|
||||
for (int j = 0; j < 8; j++)
|
||||
t = t | (((u_int64_t)(unsigned char)buffer[j+current_pos])<<(8*j));
|
||||
t = t | (((u_int64_t)(unsigned char)buffer[j + current_pos]) << (8 * j));
|
||||
current_pos += 8;
|
||||
}
|
||||
|
||||
static u_int64_t read_byte_at(int current_pos, char *buffer){
|
||||
static u_int64_t read_byte_at(int current_pos, char *buffer) {
|
||||
u_int64_t t = 0;
|
||||
for (int j = 0; j < 8; j++)
|
||||
t = t | (((u_int64_t)(unsigned char)buffer[j+current_pos])<<(8*j));
|
||||
t = t | (((u_int64_t)(unsigned char)buffer[j + current_pos]) << (8 * j));
|
||||
return t;
|
||||
}
|
||||
|
||||
void inode_construct(u_int64_t blockNumber, RawDisk &disk){
|
||||
void inode_construct(u_int64_t blockNumber, RawDisk &disk) {
|
||||
char buffer[SECTOR_SIZE] = {0};
|
||||
disk.rawdisk_read(blockNumber*SECTOR_SIZE, buffer, sizeof(buffer));
|
||||
disk.rawdisk_read(blockNumber * SECTOR_SIZE, buffer, sizeof(buffer));
|
||||
block_number = blockNumber;
|
||||
int current_pos = 0;
|
||||
// initialize blocks
|
||||
for (int i = 0; i < 48; i++){
|
||||
for (int i = 0; i < 48; i++) {
|
||||
read_get_byte(blocks[i], current_pos, buffer);
|
||||
}
|
||||
read_get_byte(single_indirect, current_pos, buffer);
|
||||
@ -102,25 +98,25 @@ public:
|
||||
read_get_byte(size, current_pos, buffer);
|
||||
}
|
||||
|
||||
void write_get_byte(u_int64_t t, int ¤t_pos, char *buffer){
|
||||
for (int j = 0; j < 8; j++){
|
||||
buffer[j+current_pos] = t & (((u_int64_t)1<<(8))-1);
|
||||
void write_get_byte(u_int64_t t, int ¤t_pos, char *buffer) {
|
||||
for (int j = 0; j < 8; j++) {
|
||||
buffer[j + current_pos] = t & (((u_int64_t)1 << (8)) - 1);
|
||||
t >>= 8;
|
||||
}
|
||||
current_pos += 8;
|
||||
}
|
||||
|
||||
static void write_byte_at(u_int64_t t, int current_pos, char *buffer){
|
||||
for (int j = 0; j < 8; j++){
|
||||
buffer[j+current_pos] = t & (((u_int64_t)1<<(8))-1);
|
||||
static void write_byte_at(u_int64_t t, int current_pos, char *buffer) {
|
||||
for (int j = 0; j < 8; j++) {
|
||||
buffer[j + current_pos] = t & (((u_int64_t)1 << (8)) - 1);
|
||||
t >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
void inode_save(RawDisk &disk){
|
||||
void inode_save(RawDisk &disk) {
|
||||
char buffer[SECTOR_SIZE] = {0};
|
||||
int current_pos = 0;
|
||||
for (int i = 0; i < 48; i++){
|
||||
for (int i = 0; i < 48; i++) {
|
||||
write_get_byte(blocks[i], current_pos, buffer);
|
||||
}
|
||||
write_get_byte(single_indirect, current_pos, buffer);
|
||||
@ -130,11 +126,11 @@ public:
|
||||
write_get_byte(gid, current_pos, buffer);
|
||||
write_get_byte(permissions, current_pos, buffer);
|
||||
write_get_byte(size, current_pos, buffer);
|
||||
disk.rawdisk_write(block_number*SECTOR_SIZE, buffer, sizeof(buffer));
|
||||
disk.rawdisk_write(block_number * SECTOR_SIZE, buffer, sizeof(buffer));
|
||||
}
|
||||
|
||||
u_int64_t datablock_allocate_in_list(RawDisk &disk){
|
||||
//find a free data block
|
||||
u_int64_t datablock_allocate_in_list(RawDisk &disk) {
|
||||
// find a free data block
|
||||
u_int64_t freeListHead = SuperBlock::getFreeListHead(disk);
|
||||
/*
|
||||
1. initialization
|
||||
@ -144,30 +140,30 @@ public:
|
||||
char buffer[IO_BLOCK_SIZE] = {0};
|
||||
u_int64_t freeBlockNum = 0;
|
||||
disk.rawdisk_read(freeListHead, buffer, sizeof(buffer));
|
||||
for (int i = 8; i < 264; i++){
|
||||
if((i < 263 && buffer[i] != -1) || (i == 263 && buffer[i] != 127)){
|
||||
for (int i = 8; i < 264; i++) {
|
||||
if ((i < 263 && buffer[i] != -1) || (i == 263 && buffer[i] != 127)) {
|
||||
int j = 0;
|
||||
for (j = 0; j < 8; j++){
|
||||
if ((buffer[i]&(1<<j)) == 0){
|
||||
buffer[i] |= (1<<j);
|
||||
for (j = 0; j < 8; j++) {
|
||||
if ((buffer[i] & (1 << j)) == 0) {
|
||||
buffer[i] |= (1 << j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j < 8){
|
||||
freeBlockNum = freeListHead + ((i-8)*8 + j + 1)*IO_BLOCK_SIZE;
|
||||
if (j < 8) {
|
||||
freeBlockNum = freeListHead + ((i - 8) * 8 + j + 1) * IO_BLOCK_SIZE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
disk.rawdisk_write(freeListHead, buffer, sizeof(buffer));
|
||||
bool notFull = false;
|
||||
for (int i = 8; i < 264; i++){
|
||||
if((i < 263 && buffer[i] != -1) || (i == 263 && buffer[i] != 127)){
|
||||
for (int i = 8; i < 264; i++) {
|
||||
if ((i < 263 && buffer[i] != -1) || (i == 263 && buffer[i] != 127)) {
|
||||
notFull = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!notFull){
|
||||
if (!notFull) {
|
||||
printf("HEADER REMOVAL DETECTED %llu %llu\n", freeListHead, freeBlockNum);
|
||||
u_int64_t next_header = read_byte_at(0, buffer);
|
||||
SuperBlock::writeFreeListHead(disk, next_header);
|
||||
@ -175,16 +171,18 @@ public:
|
||||
return freeBlockNum;
|
||||
}
|
||||
|
||||
bool allo_single_indirect(RawDisk &disk, u_int64_t &single_i, u_int64_t freeBlockNum) {
|
||||
if (single_i == 0){
|
||||
bool allo_single_indirect(RawDisk &disk, u_int64_t &single_i,
|
||||
u_int64_t freeBlockNum) {
|
||||
if (single_i == 0) {
|
||||
|
||||
single_i = datablock_allocate_in_list(disk);
|
||||
}
|
||||
bool inSingle = false;
|
||||
char buffer[IO_BLOCK_SIZE] = {0};
|
||||
disk.rawdisk_read(single_i, buffer, sizeof(buffer));
|
||||
for (int i = 0; i < IO_BLOCK_SIZE; i+=8){
|
||||
for (int i = 0; i < IO_BLOCK_SIZE; i += 8) {
|
||||
u_int64_t addr = read_byte_at(i, buffer);
|
||||
if(addr == 0){
|
||||
if (addr == 0) {
|
||||
inSingle = true;
|
||||
write_byte_at(freeBlockNum, i, buffer);
|
||||
disk.rawdisk_write(single_i, buffer, sizeof(buffer));
|
||||
@ -194,17 +192,18 @@ public:
|
||||
return inSingle;
|
||||
}
|
||||
|
||||
bool allo_double_indirect(RawDisk &disk, u_int64_t &double_i, u_int64_t freeBlockNum) {
|
||||
if (double_i == 0){
|
||||
bool allo_double_indirect(RawDisk &disk, u_int64_t &double_i,
|
||||
u_int64_t freeBlockNum) {
|
||||
if (double_i == 0) {
|
||||
double_i = datablock_allocate_in_list(disk);
|
||||
}
|
||||
bool inDouble = false;
|
||||
char buffer[IO_BLOCK_SIZE] = {0};
|
||||
disk.rawdisk_read(double_i, buffer, sizeof(buffer));
|
||||
for (int i = 0; i < IO_BLOCK_SIZE; i+=8){
|
||||
for (int i = 0; i < IO_BLOCK_SIZE; i += 8) {
|
||||
u_int64_t addr = read_byte_at(i, buffer);
|
||||
bool flag = allo_single_indirect(disk, addr, freeBlockNum);
|
||||
if (flag){
|
||||
if (flag) {
|
||||
write_byte_at(addr, i, buffer);
|
||||
disk.rawdisk_write(double_i, buffer, sizeof(buffer));
|
||||
inDouble = true;
|
||||
@ -214,17 +213,18 @@ public:
|
||||
return inDouble;
|
||||
}
|
||||
|
||||
bool allo_triple_indirect(RawDisk &disk, u_int64_t &triple_i, u_int64_t freeBlockNum) {
|
||||
if (triple_i == 0){
|
||||
bool allo_triple_indirect(RawDisk &disk, u_int64_t &triple_i,
|
||||
u_int64_t freeBlockNum) {
|
||||
if (triple_i == 0) {
|
||||
triple_i = datablock_allocate_in_list(disk);
|
||||
}
|
||||
bool inTriple = false;
|
||||
char buffer[IO_BLOCK_SIZE] = {0};
|
||||
disk.rawdisk_read(triple_i, buffer, sizeof(buffer));
|
||||
for (int i = 0; i < IO_BLOCK_SIZE; i+=8){
|
||||
for (int i = 0; i < IO_BLOCK_SIZE; i += 8) {
|
||||
u_int64_t addr = read_byte_at(i, buffer);
|
||||
bool flag = allo_double_indirect(disk, addr, freeBlockNum);
|
||||
if (flag){
|
||||
if (flag) {
|
||||
write_byte_at(addr, i, buffer);
|
||||
disk.rawdisk_write(triple_i, buffer, sizeof(buffer));
|
||||
inTriple = true;
|
||||
@ -234,54 +234,58 @@ public:
|
||||
return inTriple;
|
||||
}
|
||||
|
||||
|
||||
// allowcate 1 datablock and add to the end of the file
|
||||
u_int64_t datablock_allocate(RawDisk &disk){
|
||||
//do we need to check dynamic?
|
||||
u_int64_t datablock_allocate(RawDisk &disk) {
|
||||
// do we need to check dynamic?
|
||||
|
||||
//add the data block to blocks, single, double, triple
|
||||
// add the data block to blocks, single, double, triple
|
||||
u_int64_t freeBlockNum = datablock_allocate_in_list(disk);
|
||||
bool inBlocks = false;
|
||||
for (int i = 0; i < 48; i++)
|
||||
if(blocks[i] == 0){
|
||||
if (blocks[i] == 0) {
|
||||
inBlocks = true;
|
||||
blocks[i] = freeBlockNum;
|
||||
break;
|
||||
}
|
||||
if(!inBlocks){
|
||||
if (!inBlocks) {
|
||||
bool inSingle = allo_single_indirect(disk, single_indirect, freeBlockNum);
|
||||
if (!inSingle){
|
||||
bool inDouble = allo_double_indirect(disk, double_indirect, freeBlockNum);
|
||||
if (!inDouble){
|
||||
bool inTriple = allo_triple_indirect(disk, triple_indirect, freeBlockNum);
|
||||
if (!inSingle) {
|
||||
bool inDouble =
|
||||
allo_double_indirect(disk, double_indirect, freeBlockNum);
|
||||
if (!inDouble) {
|
||||
bool inTriple =
|
||||
allo_triple_indirect(disk, triple_indirect, freeBlockNum);
|
||||
// wait to deal with too big files
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//return the block number
|
||||
// return the block number
|
||||
inode_save(disk);
|
||||
return freeBlockNum;
|
||||
}
|
||||
|
||||
void datablock_deallocate_in_list(u_int64_t freeBlockNum, RawDisk &disk) {
|
||||
// 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};
|
||||
bool notEmpty = false;
|
||||
disk.rawdisk_read(freeBlockHead, buffer, sizeof(buffer));
|
||||
for (int i = 8; i < 264; i++){
|
||||
if(buffer[i] != 0){
|
||||
for (int i = 8; i < 264; i++) {
|
||||
if (buffer[i] != 0) {
|
||||
notEmpty = true;
|
||||
}
|
||||
}
|
||||
u_int64_t inBlockPos = (freeBlockNum-freeBlockHead)/IO_BLOCK_SIZE-1;
|
||||
buffer[8+inBlockPos/8] &= (-1)^(1<<(inBlockPos%8));
|
||||
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(!notEmpty){
|
||||
if (!notEmpty) {
|
||||
u_int64_t freeListHead = SuperBlock::getFreeListHead(disk);
|
||||
write_byte_at(freeListHead, 0, buffer);
|
||||
SuperBlock::writeFreeListHead(disk, freeBlockHead);
|
||||
@ -289,17 +293,17 @@ public:
|
||||
disk.rawdisk_write(freeBlockHead, buffer, sizeof(buffer));
|
||||
}
|
||||
|
||||
u_int64_t deallo_single_indirect(RawDisk &disk, u_int64_t &single_i){
|
||||
if (single_i == 0){
|
||||
u_int64_t deallo_single_indirect(RawDisk &disk, u_int64_t &single_i) {
|
||||
if (single_i == 0) {
|
||||
return 0;
|
||||
}
|
||||
u_int64_t freeBlockNum = 0;
|
||||
char buffer[IO_BLOCK_SIZE] = {0};
|
||||
int delpoint = -1;
|
||||
disk.rawdisk_read(single_i, buffer, sizeof(buffer));
|
||||
for (int i=4088; i >= 0; i--){
|
||||
for (int i = 4088; i >= 0; i--) {
|
||||
u_int64_t addr = read_byte_at(i, buffer);
|
||||
if(addr != 0){
|
||||
if (addr != 0) {
|
||||
freeBlockNum = addr;
|
||||
addr = 0;
|
||||
write_byte_at(addr, i, buffer);
|
||||
@ -309,25 +313,25 @@ public:
|
||||
}
|
||||
disk.rawdisk_write(single_i, buffer, sizeof(buffer));
|
||||
u_int64_t addr = read_byte_at(0, buffer);
|
||||
if (delpoint == 0 && addr == 0){
|
||||
if (delpoint == 0 && addr == 0) {
|
||||
datablock_deallocate_in_list(single_i, disk);
|
||||
single_i = 0;
|
||||
}
|
||||
return freeBlockNum;
|
||||
}
|
||||
|
||||
bool deallo_double_indirect(RawDisk &disk, u_int64_t &double_i){
|
||||
if (double_i == 0){
|
||||
bool deallo_double_indirect(RawDisk &disk, u_int64_t &double_i) {
|
||||
if (double_i == 0) {
|
||||
return false;
|
||||
}
|
||||
u_int64_t freeBlockNum = 0;
|
||||
char buffer[IO_BLOCK_SIZE] = {0};
|
||||
int delpoint = -1;
|
||||
disk.rawdisk_read(double_i, buffer, sizeof(buffer));
|
||||
for (int i=4088; i >= 0; i-=8){
|
||||
for (int i = 4088; i >= 0; i -= 8) {
|
||||
u_int64_t addr = read_byte_at(i, buffer);
|
||||
u_int64_t inSingle = deallo_single_indirect(disk, addr);
|
||||
if (inSingle){
|
||||
if (inSingle) {
|
||||
freeBlockNum = inSingle;
|
||||
write_byte_at(addr, i, buffer);
|
||||
delpoint = i;
|
||||
@ -336,25 +340,25 @@ public:
|
||||
}
|
||||
disk.rawdisk_write(double_i, buffer, sizeof(buffer));
|
||||
u_int64_t addr = read_byte_at(0, buffer);
|
||||
if (delpoint == 0 && addr == 0){
|
||||
if (delpoint == 0 && addr == 0) {
|
||||
datablock_deallocate_in_list(double_i, disk);
|
||||
double_i = 0;
|
||||
}
|
||||
return freeBlockNum;
|
||||
}
|
||||
|
||||
bool deallo_triple_indirect(RawDisk &disk, u_int64_t &triple_i){
|
||||
if (triple_i == 0){
|
||||
bool deallo_triple_indirect(RawDisk &disk, u_int64_t &triple_i) {
|
||||
if (triple_i == 0) {
|
||||
return false;
|
||||
}
|
||||
u_int64_t freeBlockNum = 0;
|
||||
char buffer[IO_BLOCK_SIZE] = {0};
|
||||
int delpoint = -1;
|
||||
disk.rawdisk_read(triple_i, buffer, sizeof(buffer));
|
||||
for (int i=4088; i >= 0; i-=8){
|
||||
for (int i = 4088; i >= 0; i -= 8) {
|
||||
u_int64_t addr = read_byte_at(i, buffer);
|
||||
u_int64_t inDouble = deallo_double_indirect(disk, addr);
|
||||
if (inDouble){
|
||||
if (inDouble) {
|
||||
freeBlockNum = inDouble;
|
||||
write_byte_at(addr, i, buffer);
|
||||
delpoint = i;
|
||||
@ -363,7 +367,7 @@ public:
|
||||
}
|
||||
disk.rawdisk_write(triple_i, buffer, sizeof(buffer));
|
||||
u_int64_t addr = read_byte_at(0, buffer);
|
||||
if (delpoint == 0 && addr == 0){
|
||||
if (delpoint == 0 && addr == 0) {
|
||||
datablock_deallocate_in_list(triple_i, disk);
|
||||
triple_i = 0;
|
||||
}
|
||||
@ -371,17 +375,17 @@ public:
|
||||
}
|
||||
|
||||
// deallocate 1 datablock from the end of the file
|
||||
u_int64_t datablock_deallocate(RawDisk &disk){
|
||||
u_int64_t datablock_deallocate(RawDisk &disk) {
|
||||
// find the last datablock and remove it from inode (triple->direct)
|
||||
u_int64_t freeBlockNum = 0;
|
||||
freeBlockNum = deallo_triple_indirect(disk, triple_indirect);
|
||||
if(!freeBlockNum){
|
||||
if (!freeBlockNum) {
|
||||
freeBlockNum = deallo_double_indirect(disk, double_indirect);
|
||||
if(!freeBlockNum){
|
||||
if (!freeBlockNum) {
|
||||
freeBlockNum = deallo_single_indirect(disk, single_indirect);
|
||||
if(!freeBlockNum){
|
||||
for(int i = 47; i>=0; i--)
|
||||
if(blocks[i] != 0){
|
||||
if (!freeBlockNum) {
|
||||
for (int i = 47; i >= 0; i--)
|
||||
if (blocks[i] != 0) {
|
||||
freeBlockNum = blocks[i];
|
||||
blocks[i] = 0;
|
||||
break;
|
||||
@ -398,67 +402,65 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class INodeOperation{
|
||||
// free list head is at super block (0): first 8 bytes
|
||||
class INodeOperation {
|
||||
// free list head is at super block (0): first 8 bytes
|
||||
|
||||
public:
|
||||
//initialization of the rawdisk
|
||||
void initialize(RawDisk &disk){
|
||||
// initialization of the rawdisk
|
||||
void initialize(RawDisk &disk) {
|
||||
// initialize Inode list head
|
||||
SuperBlock::writeFreeINodeHead(disk, 1);
|
||||
for (u_int64_t i = 1; i < MAX_INODE; i++){
|
||||
for (u_int64_t i = 1; i < MAX_INODE; i++) {
|
||||
char buffer[SECTOR_SIZE] = {0};
|
||||
u_int64_t t = i + 1;
|
||||
if (t < MAX_INODE){
|
||||
for (int j = 0; j < 8; j++){
|
||||
if (t < MAX_INODE) {
|
||||
for (int j = 0; j < 8; j++) {
|
||||
buffer[j] = (t >> (8 * j)) & 0xFF;
|
||||
}
|
||||
}
|
||||
disk.rawdisk_write(i*SECTOR_SIZE, buffer, sizeof(buffer));
|
||||
disk.rawdisk_write(i * SECTOR_SIZE, buffer, sizeof(buffer));
|
||||
}
|
||||
SuperBlock::writeFreeListHead(disk, MAX_INODE*SECTOR_SIZE); // maximum inode number 2^19 0x80000
|
||||
//Have tested this initialize function but MAX_BLOCK too much, MAX_INODE*2 works
|
||||
for (u_int64_t i = MAX_INODE; i < MAX_BLOCKNUM-4096; i += 2048*8){
|
||||
SuperBlock::writeFreeListHead(
|
||||
disk, MAX_INODE * SECTOR_SIZE); // maximum inode number 2^19 0x80000
|
||||
// Have tested this initialize function but MAX_BLOCK too much, MAX_INODE*2
|
||||
// works
|
||||
for (u_int64_t i = MAX_INODE; i < MAX_BLOCKNUM - 4096; i += 2048 * 8) {
|
||||
char buffer[IO_BLOCK_SIZE] = {0};
|
||||
u_int64_t t = (i + 2048*8)*SECTOR_SIZE;
|
||||
//t is address, storing in to buffer
|
||||
for (int j = 0; j < 8; j++){
|
||||
u_int64_t t = (i + 2048 * 8) * SECTOR_SIZE;
|
||||
// t is address, storing in to buffer
|
||||
for (int j = 0; j < 8; j++) {
|
||||
buffer[j] = (t >> (8 * j)) & 0xFF;
|
||||
}
|
||||
disk.rawdisk_write(i*SECTOR_SIZE, buffer, sizeof(buffer));
|
||||
disk.rawdisk_write(i * SECTOR_SIZE, buffer, sizeof(buffer));
|
||||
}
|
||||
}
|
||||
|
||||
// allocate an inode from free inode list head and return the number of the inode
|
||||
// the i-th inode is in the i-th block
|
||||
u_int64_t inode_allocate(RawDisk &disk){
|
||||
// allocate an inode from free inode list head and return the number of the
|
||||
// inode the i-th inode is in the i-th block
|
||||
u_int64_t inode_allocate(RawDisk &disk) {
|
||||
u_int64_t freeINodeHead = SuperBlock::getFreeINodeHead(disk);
|
||||
char buffer[SECTOR_SIZE] = {0};
|
||||
disk.rawdisk_read(freeINodeHead*SECTOR_SIZE, buffer, sizeof(buffer));
|
||||
disk.rawdisk_read(freeINodeHead * SECTOR_SIZE, buffer, sizeof(buffer));
|
||||
u_int64_t newINodeHead = INode::read_byte_at(0, buffer);
|
||||
// deal with no more INode
|
||||
SuperBlock::writeFreeINodeHead(disk, newINodeHead);
|
||||
//to do: initialize the INode on disk at freeINodeHead
|
||||
// to do: initialize the INode on disk at freeINodeHead
|
||||
|
||||
//return inode number
|
||||
// return inode number
|
||||
return freeINodeHead;
|
||||
}
|
||||
|
||||
// free the inode and add it to the free inode list head
|
||||
void inode_free(RawDisk &disk, u_int64_t INodeNumber){
|
||||
void inode_free(RawDisk &disk, u_int64_t INodeNumber) {
|
||||
u_int64_t freeINodeHead = SuperBlock::getFreeINodeHead(disk);
|
||||
char buffer[SECTOR_SIZE] = {0};
|
||||
INode::write_byte_at(freeINodeHead, 0, buffer);
|
||||
disk.rawdisk_write(INodeNumber*SECTOR_SIZE, buffer, sizeof(buffer));
|
||||
disk.rawdisk_write(INodeNumber * SECTOR_SIZE, buffer, sizeof(buffer));
|
||||
SuperBlock::writeFreeINodeHead(disk, INodeNumber);
|
||||
}
|
||||
|
||||
//ignore for now
|
||||
void inode_read(){
|
||||
// ignore for now
|
||||
void inode_read() {}
|
||||
|
||||
}
|
||||
|
||||
void inode_write(){
|
||||
|
||||
}
|
||||
void inode_write() {}
|
||||
};
|
33
include/fs.hpp
Normal file
33
include/fs.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef FS_HPP
|
||||
#define FS_HPP
|
||||
|
||||
#include "fs/datablock_allocator.hpp"
|
||||
#include "fs/fs_data_types.hpp"
|
||||
#include "fs/inode_allocator.hpp"
|
||||
#include "rawdisk.hpp"
|
||||
|
||||
#define NUM_INODE_BLOCKS 1023
|
||||
#define NUM_BLOCKS 2048
|
||||
|
||||
class Fs {
|
||||
public:
|
||||
Fs(RawDisk *disk);
|
||||
|
||||
int resize(INode_Data *inode_data, u_int64_t size, bool absolute);
|
||||
|
||||
int format();
|
||||
|
||||
// should probably be private but is not for testing
|
||||
RawDisk *disk;
|
||||
SuperBlock_Data superblock;
|
||||
INode_Allocator inode_allocator;
|
||||
DataBlock_Allocator datablock_allocator;
|
||||
|
||||
int load_superblock();
|
||||
int store_superblock();
|
||||
|
||||
int load_inode(INode_Data *inode_data);
|
||||
int store_inode(INode_Data *inode_data);
|
||||
};
|
||||
|
||||
#endif
|
32
include/fs/datablock_allocator.hpp
Normal file
32
include/fs/datablock_allocator.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef DATABLOCK_ALLOCATOR_HPP
|
||||
#define DATABLOCK_ALLOCATOR_HPP
|
||||
|
||||
class Fs;
|
||||
|
||||
class DataBlock_Allocator {
|
||||
public:
|
||||
DataBlock_Allocator(Fs *fs, u_int64_t block_segment_start,
|
||||
u_int64_t block_segment_end);
|
||||
|
||||
virtual int new_datablock(u_int64_t *block_num) = 0;
|
||||
virtual int free_datablock(u_int64_t block_num) = 0;
|
||||
|
||||
virtual int format() = 0;
|
||||
|
||||
protected:
|
||||
Fs *fs;
|
||||
u_int64_t block_segment_start, block_segment_end;
|
||||
};
|
||||
|
||||
class DataBlock_Allocator_Bitmap : DataBlock_Allocator {
|
||||
using DataBlock_Allocator::DataBlock_Allocator;
|
||||
|
||||
const int DATABLOCKS_PER_BITMAP_BLOCK = 255;
|
||||
|
||||
int new_datablock(u_int64_t *block_num) override;
|
||||
int free_datablock(u_int64_t block_num) override;
|
||||
|
||||
int format() override;
|
||||
};
|
||||
|
||||
#endif
|
45
include/fs/fs_data_types.hpp
Normal file
45
include/fs/fs_data_types.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
#ifndef FS_DATA_TYPES_HPP
|
||||
#define FS_DATA_TYPES_HPP
|
||||
|
||||
#include "rawdisk.hpp"
|
||||
|
||||
#define INODE_SIZE 512
|
||||
|
||||
size_t write_u64(u_int64_t num, char buf[]);
|
||||
|
||||
size_t read_u64(u_int64_t *num, char buf[]);
|
||||
|
||||
class SuperBlock_Data {
|
||||
u_int64_t free_list_head;
|
||||
u_int64_t inode_list_head;
|
||||
SuperBlock_Data();
|
||||
void serialize(char buf[]);
|
||||
void deserialize(char buf[]);
|
||||
};
|
||||
|
||||
class INode_Data {
|
||||
u_int64_t inode_num;
|
||||
|
||||
#define NUMBER_OF_METADATA_BYTES (4 * sizeof(u_int64_t) + sizeof(u_int32_t))
|
||||
struct INode_MetaData {
|
||||
u_int64_t uid;
|
||||
u_int64_t gid;
|
||||
u_int64_t permissions;
|
||||
u_int64_t size; // not yet implemented
|
||||
u_int32_t reference_count;
|
||||
} metadata;
|
||||
size_t serialize_metadata(char buf[]);
|
||||
size_t deserialize_metadata(char buf[]);
|
||||
|
||||
const size_t NUMBER_OF_DIRECT_BLOCKS =
|
||||
((INODE_SIZE - NUMBER_OF_METADATA_BYTES) / sizeof(u_int64_t)) - 3;
|
||||
|
||||
u_int64_t single_indirect_block, double_indirect_block, triple_indirect_block;
|
||||
u_int64_t direct_blocks[NUMBER_OF_DIRECT_BLOCKS];
|
||||
|
||||
INode_Data(u_int64_t inode_num);
|
||||
void serialize(char buf[]);
|
||||
void deserialize(char buf[]);
|
||||
};
|
||||
|
||||
#endif
|
40
include/fs/inode_allocator.hpp
Normal file
40
include/fs/inode_allocator.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
#ifndef INODE_ALLOCATOR_HPP
|
||||
#define INODE_ALLOCATOR_HPP
|
||||
|
||||
#include "fs_data_types.hpp"
|
||||
#include "rawdisk.hpp"
|
||||
|
||||
class Fs;
|
||||
|
||||
class INode_Allocator {
|
||||
public:
|
||||
const int INODES_PER_BLOCK = BLOCK_SIZE / INODE_SIZE;
|
||||
|
||||
INode_Allocator(Fs *fs, u_int64_t block_segment_start,
|
||||
u_int64_t block_segment_end);
|
||||
|
||||
virtual int new_inode(u_int64_t uid, u_int64_t gid, u_int64_t permissions,
|
||||
INode_Data *inode_data) = 0;
|
||||
virtual int free_inode(INode_Data *inode_data) = 0;
|
||||
|
||||
virtual int format() = 0;
|
||||
|
||||
u_int64_t get_block_num(INode_Data *inode_data);
|
||||
u_int64_t get_block_offset(INode_Data *inode_data);
|
||||
|
||||
protected:
|
||||
Fs *fs;
|
||||
u_int64_t block_segment_start, block_segment_end;
|
||||
};
|
||||
|
||||
class INode_Allocator_Freelist : INode_Allocator {
|
||||
using INode_Allocator::INode_Allocator;
|
||||
|
||||
int new_inode(u_int64_t uid, u_int64_t gid, u_int64_t permissions,
|
||||
INode_Data *inode_data) override;
|
||||
int free_inode(INode_Data *inode_data) override;
|
||||
|
||||
int format() override;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,82 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/fs.h>
|
||||
|
||||
class RawDisk{
|
||||
|
||||
int fd;
|
||||
const char* dir;
|
||||
u_int64_t numSectors;
|
||||
u_int64_t diskSize;
|
||||
|
||||
public:
|
||||
RawDisk(const char *directory) : fd(-1), dir(nullptr), numSectors(0), diskSize(0) {
|
||||
dir = directory;
|
||||
/*dir = strdup("/dev/vdc");
|
||||
numSectors = 62914560;
|
||||
diskSize = 32212254720;*/
|
||||
|
||||
// Open the block device (replace /dev/sdX with the actual device)
|
||||
fd = open(dir, O_RDWR); // Allow read and write
|
||||
if (fd == -1) {
|
||||
perror("Error opening device");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Use ioctl with BLKGETSIZE to get the number of sectors
|
||||
if (ioctl(fd, BLKGETSIZE64, &diskSize) == -1) {
|
||||
perror("Error getting disk size");
|
||||
close(fd);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Calculate the size in bytes
|
||||
numSectors = diskSize / 512; // Assuming a sector size of 512 bytes
|
||||
|
||||
printf("====Initializing RawDisk====\n");
|
||||
printf("Number of sectors: %llu\n", numSectors);
|
||||
printf("Disk size (in bytes): %llu\n", diskSize);
|
||||
}
|
||||
|
||||
~RawDisk() {
|
||||
if (fd != -1) {
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
int rawdisk_read(u_int64_t offset, char *buffer, size_t length) {
|
||||
if (lseek(fd, offset, SEEK_SET) == (u_int64_t)-1) {
|
||||
perror("Error seeking to offset");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssize_t bytesRead = read(fd, buffer, length);
|
||||
if (bytesRead == -1) {
|
||||
perror("Error reading from device");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Write a specified number of bytes at a given byte offset
|
||||
int rawdisk_write(u_int64_t offset, char *buffer, size_t length) {
|
||||
if (lseek(fd, offset, SEEK_SET) == (u_int64_t)-1) {
|
||||
perror("Error seeking to offset");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssize_t bytesWritten = write(fd, buffer, length);
|
||||
if (bytesWritten == -1) {
|
||||
perror("Error writing to device");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
};
|
95
include/rawdisk.hpp
Normal file
95
include/rawdisk.hpp
Normal file
@ -0,0 +1,95 @@
|
||||
#ifndef RAWDISK_HPP
|
||||
#define RAWDISK_HPP
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <linux/fs.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define BLOCK_SIZE 4096
|
||||
|
||||
class RawDisk {
|
||||
|
||||
int fd;
|
||||
const char *dir;
|
||||
u_int64_t numSectors;
|
||||
u_int64_t diskSize;
|
||||
|
||||
public:
|
||||
RawDisk(const char *directory)
|
||||
: fd(-1), dir(nullptr), numSectors(0), diskSize(0) {
|
||||
dir = directory;
|
||||
/*dir = strdup("/dev/vdc");
|
||||
numSectors = 62914560;
|
||||
diskSize = 32212254720;*/
|
||||
|
||||
// Open the block device (replace /dev/sdX with the actual device)
|
||||
fd = open(dir, O_RDWR); // Allow read and write
|
||||
if (fd == -1) {
|
||||
perror("Error opening device");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Use ioctl with BLKGETSIZE to get the number of sectors
|
||||
if (ioctl(fd, BLKGETSIZE64, &diskSize) == -1) {
|
||||
perror("Error getting disk size");
|
||||
close(fd);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Calculate the size in bytes
|
||||
numSectors = diskSize / 512; // Assuming a sector size of 512 bytes
|
||||
|
||||
printf("====Initializing RawDisk====\n");
|
||||
printf("Number of sectors: %llu\n", numSectors);
|
||||
printf("Disk size (in bytes): %llu\n", diskSize);
|
||||
}
|
||||
|
||||
~RawDisk() {
|
||||
if (fd != -1) {
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
int read_block(u_int64_t block_number, char *buffer) {
|
||||
u_int64_t offset = block_number * BLOCK_SIZE;
|
||||
|
||||
if (lseek(fd, offset, SEEK_SET) == (u_int64_t)-1) {
|
||||
perror("Error seeking to offset");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// TODO: this is incorrect
|
||||
ssize_t bytesRead = read(fd, buffer, BLOCK_SIZE);
|
||||
if (bytesRead < BLOCK_SIZE) {
|
||||
perror("Error reading from device");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Write a specified number of bytes at a given byte offset
|
||||
int write_block(u_int64_t block_number, char *buffer) {
|
||||
u_int64_t offset = block_number * BLOCK_SIZE;
|
||||
|
||||
if (lseek(fd, offset, SEEK_SET) == (u_int64_t)-1) {
|
||||
perror("Error seeking to offset");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// TODO: this is incorrect
|
||||
ssize_t bytesWritten = write(fd, buffer, BLOCK_SIZE);
|
||||
if (bytesWritten < BLOCK_SIZE) {
|
||||
perror("Error writing to device");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
75
lib/fs/datablock_allocator.cpp
Normal file
75
lib/fs/datablock_allocator.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
#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; }
|
78
lib/fs/fs.cpp
Normal file
78
lib/fs/fs.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
#include "fs.hpp"
|
||||
|
||||
Fs::Fs(RawDisk *disk) {
|
||||
disk = disk;
|
||||
superblock = SuperBlock_Data();
|
||||
inode_allocator = INode_Allocator_Freelist(this, 1, 1 + NUM_INODE_BLOCKS);
|
||||
datablock_allocator =
|
||||
DataBlock_Allocator_Bitmap(this, 1 + NUM_INODE_BLOCKS, NUM_BLOCKS);
|
||||
};
|
||||
|
||||
int Fs::format() {
|
||||
int err;
|
||||
if ((err = store_superblock()) < 0)
|
||||
return err;
|
||||
if ((err = inode_allocator.format()) < 0)
|
||||
return err;
|
||||
if ((err = datablock_allocator.format()) < 0)
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Fs::load_superblock() {
|
||||
char buf[BLOCK_SIZE];
|
||||
int err;
|
||||
|
||||
if ((err = disk->read_block(0, buf)) < 0)
|
||||
return err;
|
||||
|
||||
superblock.deserialize(buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
int Fs::store_superblock() {
|
||||
char buf[BLOCK_SIZE] = {0};
|
||||
int err;
|
||||
|
||||
superblock.serialize(buf);
|
||||
|
||||
if ((err = disk->write_block(0, buf)) < 0)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Fs::load_inode(INode_Data *inode_data) {
|
||||
char buf[BLOCK_SIZE];
|
||||
int err;
|
||||
|
||||
u_int64_t block_num = inode_allocator.get_block_num(inode_data);
|
||||
if (block_num == 0)
|
||||
return -1;
|
||||
u_int64_t block_offset = inode_allocator.get_block_offset(inode_data);
|
||||
|
||||
if ((err = disk->read_block(block_num, buf)) < 0)
|
||||
return err;
|
||||
|
||||
inode_data->deserialize(&buf[block_offset])
|
||||
|
||||
return 0;
|
||||
}
|
||||
int Fs::store_inode(INode_Data *inode_data) {
|
||||
char buf[BLOCK_SIZE];
|
||||
int err;
|
||||
|
||||
u_int64_t block_num = inode_allocator.get_block_num(inode_data);
|
||||
if (block_num == 0)
|
||||
return -1;
|
||||
u_int64_t block_offset = inode_allocator.get_block_offset(inode_data);
|
||||
|
||||
if ((err = disk->read_block(block_num, buf)) < 0)
|
||||
return err;
|
||||
|
||||
inode_data->serialize(&buf[block_offset])
|
||||
|
||||
if ((err = disk->write_block(block_num, buf)) < 0) return err;
|
||||
|
||||
return 0;
|
||||
}
|
89
lib/fs/fs_data_types.cpp
Normal file
89
lib/fs/fs_data_types.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
#include "fs.hpp"
|
||||
|
||||
size_t write_u64(u_int64_t num, char buf[]) {
|
||||
size_t i = 0;
|
||||
for (; i < 8; ++i)
|
||||
buf[i] = (char)(num >> (i * 8));
|
||||
return i;
|
||||
}
|
||||
|
||||
size_t read_u64(u_int64_t *num, char buf[]) {
|
||||
size_t i = 0;
|
||||
(*num) = 0;
|
||||
for (; i < 8; ++i) {
|
||||
(*num) <<= 8;
|
||||
(*num) |= ((u_int64_t)buf[i]) & 0xFF;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
SuperBlock_Data::SuperBlock_Data() {
|
||||
free_list_head = 0;
|
||||
inode_list_head = 0;
|
||||
}
|
||||
|
||||
SuperBlock_Data::serialize(char buf[]) {
|
||||
size_t i = 0;
|
||||
i += write_u64(free_list_head, &buf[i]);
|
||||
i += write_u64(inode_list_head, &buf[i]);
|
||||
}
|
||||
|
||||
SuperBlock_Data::deserialize(char buf[]) {
|
||||
size_t i = 0;
|
||||
i += read_u64(&free_list_head, &buf[i]);
|
||||
i += read_u64(&inode_list_head, &buf[i]);
|
||||
}
|
||||
|
||||
INode_Data::INode_Data(u_int64_t inode_num) {
|
||||
inode_num = inode_num;
|
||||
|
||||
metadata.uid = -1;
|
||||
metadata.gid = -1;
|
||||
metadata.permissions = -1;
|
||||
metadata.size = 0;
|
||||
metadata.reference_count = 0;
|
||||
|
||||
single_indirect_block = double_indirect_block = triple_indirect_block = 0;
|
||||
|
||||
for (size_t i = 0; i < NUMBER_OF_DIRECT_BLOCKS; ++i)
|
||||
direct_blocks[i] = 0;
|
||||
}
|
||||
|
||||
size_t INode_Data::serialize_metadata(char buf[]) {
|
||||
size_t i = 0;
|
||||
i += write_u64(metadata.uid, &buf[i]);
|
||||
i += write_u64(metadata.gid, &buf[i]);
|
||||
i += write_u64(metadata.permissions, &buf[i]);
|
||||
i += write_u64(metadata.size, &buf[i]);
|
||||
i += write_u64(metadata.reference_count, &buf[i]);
|
||||
return i;
|
||||
}
|
||||
|
||||
size_t INode_Data::deserialize_metadata(char buf[]) {
|
||||
size_t i = 0;
|
||||
i += read_u64(&metadata.uid, &buf[i]);
|
||||
i += read_u64(&metadata.gid, &buf[i]);
|
||||
i += read_u64(&metadata.permissions, &buf[i]);
|
||||
i += read_u64(&metadata.size, &buf[i]);
|
||||
i += read_u64(&metadata.reference_count, &buf[i]);
|
||||
return i;
|
||||
}
|
||||
|
||||
void INode_Data::serialize(char buf[]) {
|
||||
size_t i = 0;
|
||||
i += serialize_metadata(&buf[i]);
|
||||
i += write_u64(triple_indirect_block, &buf[i]);
|
||||
i += write_u64(double_indirect_block, &buf[i]);
|
||||
i += write_u64(single_indirect_block, &buf[i]);
|
||||
for (size_t j = 0; j < NUMBER_OF_DIRECT_BLOCKS; ++j)
|
||||
i += write_u64(direct_blocks[j], &buf[i]);
|
||||
}
|
||||
void INode_Data::deserialize(char buf[]) {
|
||||
size_t i = 0;
|
||||
i += deserialize_metadata(&buf[i]);
|
||||
i += read_u64(&triple_indirect_block, &buf[i]);
|
||||
i += read_u64(&double_indirect_block, &buf[i]);
|
||||
i += read_u64(&single_indirect_block, &buf[i]);
|
||||
for (size_t j = 0; j < NUMBER_OF_DIRECT_BLOCKS; ++j)
|
||||
i += read_u64(&direct_blocks[j], &buf[i]);
|
||||
}
|
0
lib/fs/fs_resize.cpp
Normal file
0
lib/fs/fs_resize.cpp
Normal file
29
lib/fs/inode_allocator.cpp
Normal file
29
lib/fs/inode_allocator.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
#include "fs.hpp"
|
||||
|
||||
INode_Allocator::INode_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;
|
||||
}
|
||||
|
||||
u_int64_t INode_Allocator::get_block_num(INode_Data *inode_data) {
|
||||
u_int64_t block_num =
|
||||
block_segment_start + (inode_data->inode_num / INODES_PER_BLOCK);
|
||||
if (block_num >= block_segment_end)
|
||||
return 0;
|
||||
return block_num;
|
||||
}
|
||||
u_int64_t INode_Allocator::get_block_offset(INode_Data *inode_data) {
|
||||
return (inode_data->inode_num % INODES_PER_BLOCK) * INODE_SIZE;
|
||||
}
|
||||
|
||||
int INode_Allocator_Freelist::new_inode(u_int64_t uid, u_int64_t gid,
|
||||
u_int64_t permissions,
|
||||
INode_Data *inode_data) {
|
||||
(*inode_data) = nullptr;
|
||||
return -1;
|
||||
}
|
||||
int INode_Allocator_Freelist::free_inode(INode_Data *inode_data) { return -1; }
|
||||
|
||||
int INode_Allocator_Freelist::format() { return -1; }
|
Loading…
x
Reference in New Issue
Block a user