diff --git a/.DS_Store b/.DS_Store index 4c4a626..07b8666 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/include/fischl.h b/include/fischl.h deleted file mode 100644 index 7226576..0000000 --- a/include/fischl.h +++ /dev/null @@ -1,7 +0,0 @@ -class fischl{ - - // declare - public: - int init(); - -}; \ No newline at end of file diff --git a/include/fs.h b/include/fs.h deleted file mode 100644 index 63da3f6..0000000 --- a/include/fs.h +++ /dev/null @@ -1,470 +0,0 @@ -#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) - -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 - -class SuperBlock{ - -public: - SuperBlock(){ - - } - ~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)); - return t; - } - - static void writeFreeListHead(RawDisk &disk, u_int64_t t){ - char buffer[8] = {0}; - 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){ - 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)); - return t; - } - - static void writeFreeINodeHead(RawDisk &disk, u_int64_t t){ - char buffer[8] = {0}; - for (int j = 0; j < 8; j++){ - buffer[j] = (t >> (8 * j)) & 0xFF; - } - disk.rawdisk_write(8, buffer, sizeof(buffer)); - } -}; - -class INode{ - // direct datablocks - u_int64_t blocks[48]; - // indirect address - u_int64_t single_indirect, double_indirect, triple_indirect; - // other - - u_int64_t uid; - u_int64_t gid; - u_int64_t permissions; - u_int64_t size; - u_int64_t block_number; - -public: - 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)); - current_pos += 8; - } - - 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)); - return t; - } - - void inode_construct(u_int64_t blockNumber, RawDisk &disk){ - char buffer[SECTOR_SIZE] = {0}; - 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++){ - read_get_byte(blocks[i], current_pos, buffer); - } - read_get_byte(single_indirect, current_pos, buffer); - read_get_byte(double_indirect, current_pos, buffer); - read_get_byte(triple_indirect, current_pos, buffer); - read_get_byte(uid, current_pos, buffer); - read_get_byte(gid, current_pos, buffer); - read_get_byte(permissions, current_pos, buffer); - 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); - 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); - t >>= 8; - } - } - - void inode_save(RawDisk &disk){ - char buffer[SECTOR_SIZE] = {0}; - int current_pos = 0; - for (int i = 0; i < 48; i++){ - write_get_byte(blocks[i], current_pos, buffer); - } - write_get_byte(single_indirect, current_pos, buffer); - write_get_byte(double_indirect, current_pos, buffer); - write_get_byte(triple_indirect, current_pos, buffer); - write_get_byte(uid, current_pos, buffer); - 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)); - } - - u_int64_t datablock_allocate_in_list(RawDisk &disk){ - //find a free data block - u_int64_t freeListHead = SuperBlock::getFreeListHead(disk); - /* - 1. initialization - 2. data block starting position - 3. r/w between storage and rawdisk to maintain - */ - 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)){ - int j = 0; - for (j = 0; j < 8; j++){ - if ((buffer[i]&(1<= 0; i-=8){ - u_int64_t addr = read_byte_at(i, buffer); - if(addr != 0){ - freeBlockNum = addr; - addr = 0; - write_byte_at(addr, i, buffer); - delpoint = i; - break; - } - } - disk.rawdisk_write(single_i, buffer, sizeof(buffer)); - u_int64_t addr = read_byte_at(0, buffer); - if (delpoint == 0 && addr == 0){ - datablock_deallocate_in_list(single_i, disk); - single_i = 0; - } - return freeBlockNum; - } - - u_int64_t 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){ - u_int64_t addr = read_byte_at(i, buffer); - u_int64_t inSingle = deallo_single_indirect(disk, addr); - if (inSingle){ - freeBlockNum = inSingle; - write_byte_at(addr, i, buffer); - delpoint = i; - break; - } - } - disk.rawdisk_write(double_i, buffer, sizeof(buffer)); - u_int64_t addr = read_byte_at(0, buffer); - if (delpoint == 0 && addr == 0){ - datablock_deallocate_in_list(double_i, disk); - double_i = 0; - } - return freeBlockNum; - } - - u_int64_t 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){ - u_int64_t addr = read_byte_at(i, buffer); - u_int64_t inDouble = deallo_double_indirect(disk, addr); - if (inDouble){ - freeBlockNum = inDouble; - write_byte_at(addr, i, buffer); - delpoint = i; - break; - } - } - disk.rawdisk_write(triple_i, buffer, sizeof(buffer)); - u_int64_t addr = read_byte_at(0, buffer); - if (delpoint == 0 && addr == 0){ - datablock_deallocate_in_list(triple_i, disk); - triple_i = 0; - } - return freeBlockNum; - } - - // deallocate 1 datablock from the end of the file - 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){ - freeBlockNum = deallo_double_indirect(disk, double_indirect); - if(!freeBlockNum){ - freeBlockNum = deallo_single_indirect(disk, single_indirect); - if(!freeBlockNum){ - for(int i = 47; i>=0; i--) - if(blocks[i] != 0){ - freeBlockNum = blocks[i]; - blocks[i] = 0; - break; - } - // deal with empty - } - } - } - - // add it back to freeBlocklist - datablock_deallocate_in_list(freeBlockNum, disk); - inode_save(disk); - return freeBlockNum; - } -}; - -class INodeOperation{ -// free list head is at super block (0): first 8 bytes - -public: - //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++){ - char buffer[SECTOR_SIZE] = {0}; - u_int64_t t = i + 1; - 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)); - } - 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++){ - buffer[j] = (t >> (8 * j)) & 0xFF; - } - 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){ - u_int64_t freeINodeHead = SuperBlock::getFreeINodeHead(disk); - char buffer[SECTOR_SIZE] = {0}; - 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 - - //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){ - 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)); - SuperBlock::writeFreeINodeHead(disk, INodeNumber); - } - - //ignore for now - void inode_read(){ - - } - - void inode_write(){ - - } -}; \ No newline at end of file diff --git a/include/rawdisk.h b/include/rawdisk.h deleted file mode 100644 index 4cccf70..0000000 --- a/include/rawdisk.h +++ /dev/null @@ -1,82 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -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; - } - -}; \ No newline at end of file diff --git a/lib/fischl.cpp b/lib/fischl.cpp index 3cc7ad7..5b7ffae 100644 --- a/lib/fischl.cpp +++ b/lib/fischl.cpp @@ -1,8 +1,66 @@ -#include "fischl.h" +#define FUSE_USE_VERSION 31 -#include +#include +#include +#include +#include +#include +#include +#include -int fischl::init(){ - printf("Hello Fischl!"); - return 3; +static int fischl_mkdir(const char *, mode_t) { + + return 0; +} + +static int fischl_open(const char *path, struct fuse_file_info *fi) { + + return 0; +} + +static const struct fuse_operations fischl_oper = { + .init = fischl_init, + .getattr = fischl_getattr, + .readdir = fischl_readdir, + .open = fischl_open, + .mkdir = fischl_mkdir, + .read = fischl_read, +}; + +static void show_help(const char *progname) +{ + printf("usage: %s [options] \n\n", progname); + printf("File-system specific options:\n" + " --name= Name of the \"hello\" file\n" + " (default: \"hello\")\n" + " --contents= Contents \"hello\" file\n" + " (default \"Hello, World!\\n\")\n" + "\n"); +} + +int main(int argc, char *argv[]) +{ + int ret; + struct fuse_args args = FUSE_ARGS_INIT(argc, argv); + + + + /* Parse options */ + if (fuse_opt_parse(&args, &options, option_spec, NULL) == -1) + return 1; + + /* When --help is specified, first print our own file-system + specific help text, then signal fuse_main to show + additional help (by adding `--help` to the options again) + without usage: line (by setting argv[0] to the empty + string) */ + if (options.show_help) { + show_help(argv[0]); + assert(fuse_opt_add_arg(&args, "--help") == 0); + args.argv[0][0] = '\0'; + } + + ret = fuse_main(args.argc, args.argv, &hello_oper, NULL); + fuse_opt_free_args(&args); + return ret; } \ No newline at end of file diff --git a/lib/main.cpp b/lib/main.cpp index 396b885..e7ad5c2 100644 --- a/lib/main.cpp +++ b/lib/main.cpp @@ -2,8 +2,7 @@ #include "rawdisk.h" int main(){ - fischl *F = new fischl; - F->init(); + fischl(); char *d = strdup("/dev/vdc"); RawDisk *H = new RawDisk(d); return 0;