make code compile, but doesn't pass test_layer2_API
This commit is contained in:
parent
b58d24d233
commit
8bdf353fda
@ -20,10 +20,10 @@ typedef struct treeNode {
|
||||
} TreeNode;
|
||||
|
||||
/*for root*/
|
||||
TreeNode *fischl_init_entry(int new_inode_number, const char *fileName, INode *new_inode);
|
||||
TreeNode *fischl_init_entry(int new_inode_number, const char *fileName, INode_Data *new_inode);
|
||||
/*the to be added file in add_entry should be parent-child relationship with treenode, otherwise will wrong */
|
||||
/*see Add_FindFiletest in dir_API.cpp*/
|
||||
int fischl_add_entry(TreeNode *parent, int new_inode_number, const char *fileName, INode *new_inode);
|
||||
int fischl_add_entry(TreeNode *parent, int new_inode_number, const char *fileName, INode_Data *new_inode);
|
||||
int fischl_rm_entry(TreeNode *parent, const char *fileName);
|
||||
/*if want to use dir mode use the subdirectory treeNode pointer */
|
||||
//e.g. FileNode *Dirnode = fischl_find_entry(); can see file inside with Dirnode->subdirectory
|
||||
|
@ -1,22 +1,21 @@
|
||||
#include <sys/types.h>
|
||||
#include <fs.h>
|
||||
#include <fs.hpp>
|
||||
#include "fuse_common.h"
|
||||
#include "direntry.h"
|
||||
|
||||
class FilesOperation {
|
||||
RawDisk& disk;
|
||||
INodeOperation inop;
|
||||
INode* new_inode(u_int64_t inode_number, u_int64_t permissions);
|
||||
void create_dot_dotdot(INode*, u_int64_t);
|
||||
Fs *fs;
|
||||
void create_dot_dotdot(INode_Data*, u_int64_t);
|
||||
|
||||
public:
|
||||
TreeNode *root_node;
|
||||
FilesOperation(RawDisk&);
|
||||
int read_datablock(const INode& inode, u_int64_t index, char* buffer);
|
||||
int write_datablock(INode& inode, u_int64_t index, const char* buffer);
|
||||
FilesOperation(RawDisk&, Fs*);
|
||||
int read_datablock(const INode_Data& inode, u_int64_t index, char* buffer);
|
||||
int write_datablock(INode_Data& inode, u_int64_t index, char* buffer);
|
||||
void initialize_rootinode();
|
||||
void printDirectory(u_int64_t);
|
||||
INode* create_new_inode(u_int64_t parent_inode_number, const char* name, mode_t mode);
|
||||
INode_Data* create_new_inode(u_int64_t parent_inode_number, const char* name, mode_t mode);
|
||||
void unlink_inode(u_int64_t inode_number);
|
||||
u_int64_t disk_namei(const char* path);
|
||||
u_int64_t namei(const char* path);
|
||||
|
@ -43,7 +43,7 @@ public:
|
||||
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 = 0xFFFFFFFFFFFFFFFF);
|
||||
INode_Data(u_int64_t inode_num = (u_int64_t)(0xFFFFFFFFFFFFFFFF));
|
||||
void serialize(char buf[]);
|
||||
void deserialize(char buf[]);
|
||||
};
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "fs.h"
|
||||
#include "fs.hpp"
|
||||
#include "direntry.h"
|
||||
/*********************************Hash operation********************************************
|
||||
|
||||
@ -151,7 +151,7 @@ void freeTree(TreeNode *node) {
|
||||
|
||||
********************************************************************************************/
|
||||
//for fake root (mount point)
|
||||
TreeNode *fischl_init_entry(int new_inode_number, const char *fileName, INode *new_inode) {
|
||||
TreeNode *fischl_init_entry(int new_inode_number, const char *fileName, INode_Data *new_inode) {
|
||||
TreeNode *newDir = (TreeNode *)malloc(sizeof(TreeNode));
|
||||
newDir->dirName = strdup(fileName);
|
||||
newDir->contents = createHashTable(20);//hashSize define 20
|
||||
@ -159,17 +159,17 @@ TreeNode *fischl_init_entry(int new_inode_number, const char *fileName, INode *n
|
||||
FileNode *newFile = (FileNode *)malloc(sizeof(FileNode));
|
||||
newFile->name = strdup(fileName);
|
||||
newFile->inode_number = new_inode_number;
|
||||
newFile->permissions = new_inode->permissions;
|
||||
newFile->permissions = new_inode->metadata.permissions;
|
||||
newFile->subdirectory = newDir;
|
||||
newDir->self_info = newFile;
|
||||
return newDir;
|
||||
}
|
||||
|
||||
int fischl_add_entry(TreeNode *parent, int new_inode_number, const char *fileName, INode *new_inode){
|
||||
int fischl_add_entry(TreeNode *parent, int new_inode_number, const char *fileName, INode_Data *new_inode){
|
||||
char *Name = strdup(fileName);
|
||||
TreeNode *newDir = NULL;
|
||||
/*If directory, malloc TreeNode, and then create filenode that belongs to Parent hash table content*/
|
||||
if ((new_inode->permissions & S_IFMT) == S_IFDIR) {
|
||||
if ((new_inode->metadata.permissions & S_IFMT) == S_IFDIR) {
|
||||
newDir = (TreeNode *)malloc(sizeof(TreeNode));
|
||||
newDir->dirName = Name;
|
||||
newDir->contents = createHashTable(20);//hasSize define 20
|
||||
@ -177,7 +177,7 @@ int fischl_add_entry(TreeNode *parent, int new_inode_number, const char *fileNam
|
||||
}
|
||||
FileNode *newFile = insertHash(parent->contents, Name, newDir); //newDir == NULL indicates it's a file
|
||||
//assign INode *new_inode metadata to data member in FileNode structure
|
||||
newFile->permissions = new_inode->permissions;
|
||||
newFile->permissions = new_inode->metadata.permissions;
|
||||
newFile->inode_number = new_inode_number;
|
||||
//Diretory have its own file information, that is . here
|
||||
if(newDir != NULL)
|
||||
|
194
lib/files.cpp
194
lib/files.cpp
@ -23,81 +23,71 @@ struct DirectoryEntry {
|
||||
}
|
||||
};
|
||||
|
||||
FilesOperation::FilesOperation(RawDisk& disk_): disk(disk_) {
|
||||
inop.initialize(disk);
|
||||
FilesOperation::FilesOperation(RawDisk& disk_, Fs* fs): disk(disk_) {
|
||||
this->fs = fs;
|
||||
}
|
||||
|
||||
u_int64_t index_to_offset(const INode& inode, RawDisk& disk, u_int64_t index) {
|
||||
u_int64_t index_to_offset(const INode_Data& inode, RawDisk& disk, u_int64_t index) {
|
||||
u_int64_t ret;
|
||||
u_int64_t offset;
|
||||
if (index < 48) {
|
||||
return inode.blocks[index];
|
||||
return inode.direct_blocks[index];
|
||||
} else if (index < 48 + 512){
|
||||
char indirect_buffer[IO_BLOCK_SIZE] = {0};
|
||||
disk.rawdisk_read(inode.single_indirect, indirect_buffer, IO_BLOCK_SIZE);
|
||||
return INode::read_byte_at(8*(index-48), indirect_buffer);
|
||||
disk.read_block(inode.single_indirect_block/IO_BLOCK_SIZE, indirect_buffer);
|
||||
read_u64(&ret, indirect_buffer+8*(index-48));
|
||||
return ret;
|
||||
} else if (index < 48 + 512 + 512*512) {
|
||||
char indirect_buffer[IO_BLOCK_SIZE] = {0};
|
||||
disk.rawdisk_read(inode.double_indirect, indirect_buffer, IO_BLOCK_SIZE);
|
||||
u_int64_t offset = INode::read_byte_at(8*((index-48-512)/512), indirect_buffer);
|
||||
disk.rawdisk_read(offset,indirect_buffer, IO_BLOCK_SIZE);
|
||||
return INode::read_byte_at(8*((index-48-512)%512), indirect_buffer);
|
||||
disk.read_block(inode.double_indirect_block/IO_BLOCK_SIZE, indirect_buffer);
|
||||
read_u64(&offset, indirect_buffer+8*((index-48-512)/512));
|
||||
disk.read_block(offset/IO_BLOCK_SIZE,indirect_buffer);
|
||||
read_u64(&ret, indirect_buffer+8*((index-48-512)%512));
|
||||
return ret;
|
||||
} else if (index < 48 + 512 + 512*512 + 512*512*512){
|
||||
char indirect_buffer[IO_BLOCK_SIZE] = {0};
|
||||
disk.rawdisk_read(inode.triple_indirect, indirect_buffer, IO_BLOCK_SIZE);
|
||||
u_int64_t offset = INode::read_byte_at(8*((index-48-512-512*512)/(512*512)), indirect_buffer);
|
||||
disk.rawdisk_read(offset,indirect_buffer, IO_BLOCK_SIZE);
|
||||
offset = INode::read_byte_at(8*(((index-48-512-512*512)%(512*512))/512), indirect_buffer);
|
||||
disk.rawdisk_read(offset,indirect_buffer, IO_BLOCK_SIZE);
|
||||
return INode::read_byte_at(8*((index-48-512-512*512)%512), indirect_buffer);
|
||||
disk.read_block(inode.triple_indirect_block/IO_BLOCK_SIZE, indirect_buffer);
|
||||
read_u64(&offset, indirect_buffer+8*((index-48-512-512*512)/(512*512)));
|
||||
disk.read_block(offset/IO_BLOCK_SIZE,indirect_buffer);
|
||||
read_u64(&offset, indirect_buffer+8*(((index-48-512-512*512)%(512*512))/512));
|
||||
disk.read_block(offset/IO_BLOCK_SIZE,indirect_buffer);
|
||||
read_u64(&ret, indirect_buffer+8*((index-48-512-512*512)%512));
|
||||
return ret;
|
||||
} else {
|
||||
printf("index out of range, tried to access index %llu, max index %llu\n", index, 48+512+512*512+512*512*512);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int FilesOperation::read_datablock(const INode& inode, u_int64_t index, char* buffer) {
|
||||
if (index >= inode.size) {
|
||||
printf("Read datablock out of range, inode number %llu", inode.block_number);
|
||||
int FilesOperation::read_datablock(const INode_Data& inode, u_int64_t index, char* buffer) {
|
||||
if (index >= inode.metadata.size) {
|
||||
printf("Read datablock out of range, inode number %llu", inode.inode_num);
|
||||
return -1;
|
||||
}
|
||||
u_int64_t read_offset = index_to_offset(inode, disk, index);
|
||||
if (read_offset == (u_int64_t)(-1)) {
|
||||
return -1;
|
||||
}
|
||||
return disk.rawdisk_read(read_offset, buffer, IO_BLOCK_SIZE);
|
||||
return disk.read_block(read_offset/IO_BLOCK_SIZE, buffer);
|
||||
}
|
||||
|
||||
int FilesOperation::write_datablock(INode& inode, u_int64_t index, const char* buffer) {
|
||||
while (index >= inode.size) {
|
||||
u_int64_t ret = inode.datablock_allocate(disk);
|
||||
inode.size += 1;
|
||||
int FilesOperation::write_datablock(INode_Data& inode, u_int64_t index, char* buffer) {
|
||||
while (index >= inode.metadata.size) {
|
||||
u_int64_t alloc_num;
|
||||
fs->allocate_datablock(&inode, &alloc_num);
|
||||
inode.metadata.size += 1;
|
||||
}
|
||||
u_int64_t write_offset = index_to_offset(inode, disk, index);
|
||||
if (write_offset == (u_int64_t)(-1)) {
|
||||
return -1;
|
||||
}
|
||||
return disk.rawdisk_write(write_offset, buffer, IO_BLOCK_SIZE);
|
||||
return disk.write_block(write_offset/IO_BLOCK_SIZE, buffer);
|
||||
}
|
||||
|
||||
INode* FilesOperation::new_inode(u_int64_t inode_number, u_int64_t permissions) {
|
||||
// zero out disk space of inode, because in memory inode is uninitialized by default
|
||||
char buffer[SECTOR_SIZE] = {0};
|
||||
disk.rawdisk_write(inode_number*SECTOR_SIZE, buffer, sizeof(buffer));
|
||||
INode *inode = new INode;
|
||||
inode->inode_construct(inode_number, disk);
|
||||
inode->block_number = inode_number;
|
||||
inode->permissions = permissions;
|
||||
inode->inode_save(disk);
|
||||
|
||||
return inode;
|
||||
}
|
||||
|
||||
void FilesOperation::create_dot_dotdot(INode* inode, u_int64_t parent_inode_number) {
|
||||
if(inode->size != 0) {
|
||||
printf("Error: create_dot_dotdot should only be called on new inode for directory\n");
|
||||
}
|
||||
void FilesOperation::create_dot_dotdot(INode_Data* inode, u_int64_t parent_inode_number) {
|
||||
char buffer[IO_BLOCK_SIZE] = {0};
|
||||
DirectoryEntry dot;
|
||||
dot.inode_number = inode->block_number;
|
||||
dot.inode_number = inode->inode_num;
|
||||
strcpy(dot.file_name, ".");
|
||||
dot.serialize(buffer);
|
||||
DirectoryEntry dotdot;
|
||||
@ -105,24 +95,27 @@ void FilesOperation::create_dot_dotdot(INode* inode, u_int64_t parent_inode_numb
|
||||
strcpy(dotdot.file_name, "..");
|
||||
dotdot.serialize(buffer+264);
|
||||
int ret = write_datablock(*inode, 0, buffer);
|
||||
inode->inode_save(disk);
|
||||
}
|
||||
|
||||
void FilesOperation::initialize_rootinode() {
|
||||
// this method must be called explicitly right after initializion
|
||||
u_int64_t root_inode_number = inop.inode_allocate(disk);
|
||||
// printf("Info: root inode number: %llu\n", root_inode_number);
|
||||
INode *root_inode = new_inode(root_inode_number, S_IFDIR);
|
||||
INode_Data *root_inode = new INode_Data();
|
||||
printf("OK0\n");
|
||||
fs->inode_manager->new_inode(0, 0, S_IFDIR, root_inode);
|
||||
printf("OK1\n");
|
||||
u_int64_t root_inode_number = root_inode->inode_num;
|
||||
printf("OK2\n");
|
||||
create_dot_dotdot(root_inode, root_inode_number);
|
||||
root_node = fischl_init_entry(root_inode_number, "/", root_inode);
|
||||
assert(root_node->self_info!=NULL);
|
||||
delete root_inode;
|
||||
fs->inode_manager->save_inode(root_inode);
|
||||
}
|
||||
|
||||
void FilesOperation::printDirectory(u_int64_t inode_number) {
|
||||
// limit to first datablock
|
||||
INode inode;
|
||||
inode.inode_construct(inode_number, disk);
|
||||
INode_Data inode;
|
||||
inode.inode_num = inode_number;
|
||||
fs->inode_manager->load_inode(&inode);
|
||||
char buffer[IO_BLOCK_SIZE] = {0};
|
||||
read_datablock(inode, 0, buffer);
|
||||
DirectoryEntry ent;
|
||||
@ -133,22 +126,23 @@ void FilesOperation::printDirectory(u_int64_t inode_number) {
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
INode* FilesOperation::create_new_inode(u_int64_t parent_inode_number, const char* name, mode_t mode) {
|
||||
INode_Data* FilesOperation::create_new_inode(u_int64_t parent_inode_number, const char* name, mode_t mode) {
|
||||
// trys to create a file under parent directory
|
||||
if (strlen(name)>=256) {
|
||||
perror("Name too long, cannot create file or directory");
|
||||
return NULL;
|
||||
}
|
||||
INode inode;
|
||||
inode.inode_construct(parent_inode_number, disk);
|
||||
if ((inode.permissions & S_IFMT) != S_IFDIR) {
|
||||
INode_Data inode;
|
||||
inode.inode_num = parent_inode_number;
|
||||
fs->inode_manager->save_inode(&inode);
|
||||
if ((inode.metadata.permissions & S_IFMT) != S_IFDIR) {
|
||||
fprintf(stderr,"[%s ,%d] please create under directory\n",__func__,__LINE__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Check if file or directory already exists
|
||||
char r_buffer[IO_BLOCK_SIZE] = {0};
|
||||
for (u_int64_t idx=0; idx<inode.size; idx++) {
|
||||
for (u_int64_t idx=0; idx<inode.metadata.size; idx++) {
|
||||
read_datablock(inode, idx, r_buffer);
|
||||
DirectoryEntry ent;
|
||||
for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){
|
||||
@ -164,45 +158,44 @@ INode* FilesOperation::create_new_inode(u_int64_t parent_inode_number, const cha
|
||||
}
|
||||
}
|
||||
|
||||
u_int64_t new_inode_number = 0;
|
||||
bool allocated = false;
|
||||
INode_Data *new_inode;
|
||||
fs->inode_manager->new_inode(0, 0, mode, new_inode);
|
||||
if ((mode & S_IFMT) == S_IFDIR) {
|
||||
create_dot_dotdot(new_inode, parent_inode_number);
|
||||
}
|
||||
|
||||
char rw_buffer[IO_BLOCK_SIZE] = {0};
|
||||
for (u_int64_t idx=0; idx<inode.size; idx++) {
|
||||
for (u_int64_t idx=0; idx<inode.metadata.size; idx++) {
|
||||
read_datablock(inode, idx, rw_buffer);
|
||||
DirectoryEntry ent;
|
||||
for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){
|
||||
ent.deserialize(rw_buffer+i);
|
||||
if (ent.inode_number == 0) {
|
||||
new_inode_number = inop.inode_allocate(disk);
|
||||
ent.inode_number = new_inode_number;
|
||||
allocated = true;
|
||||
ent.inode_number = new_inode->inode_num;
|
||||
strcpy(ent.file_name, name);
|
||||
ent.serialize(rw_buffer+i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (new_inode_number) {
|
||||
if (allocated) {
|
||||
write_datablock(inode, idx, rw_buffer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!new_inode_number) {
|
||||
if (!allocated) {
|
||||
char write_buffer[IO_BLOCK_SIZE] = {0};
|
||||
DirectoryEntry ent;
|
||||
new_inode_number = inop.inode_allocate(disk);
|
||||
ent.inode_number = new_inode_number;
|
||||
ent.inode_number = new_inode->inode_num;
|
||||
strcpy(ent.file_name, name);
|
||||
ent.serialize(write_buffer);
|
||||
write_datablock(inode, inode.size, write_buffer);
|
||||
inode.inode_save(disk);
|
||||
write_datablock(inode, inode.metadata.size, write_buffer);
|
||||
fs->inode_manager->save_inode(&inode);
|
||||
}
|
||||
|
||||
// initialize new file
|
||||
INode *get_inode = new_inode(new_inode_number, mode);
|
||||
if ((get_inode->permissions & S_IFMT) == S_IFDIR) {
|
||||
create_dot_dotdot(get_inode, parent_inode_number);
|
||||
}
|
||||
return get_inode;
|
||||
return new_inode;
|
||||
}
|
||||
|
||||
u_int64_t FilesOperation::disk_namei(const char* path) {
|
||||
@ -217,16 +210,17 @@ u_int64_t FilesOperation::disk_namei(const char* path) {
|
||||
return -1;
|
||||
}
|
||||
while (std::getline(pathStream, new_name, '/')) {
|
||||
INode inode;
|
||||
inode.inode_construct(current_inode, disk);
|
||||
if ((inode.permissions & S_IFMT) != S_IFDIR || inode.size == 0) {
|
||||
INode_Data inode;
|
||||
inode.inode_num = current_inode;
|
||||
fs->inode_manager->load_inode(&inode);
|
||||
if ((inode.metadata.permissions & S_IFMT) != S_IFDIR || inode.metadata.size == 0) {
|
||||
printf("disk_namei: %s is not a non-empty directory\n", current_dirname.c_str());
|
||||
return -1;
|
||||
}
|
||||
u_int64_t new_inode_number = 0;
|
||||
|
||||
char buffer[IO_BLOCK_SIZE] = {0};
|
||||
for(u_int64_t idx=0; idx<inode.size; idx++) {
|
||||
for(u_int64_t idx=0; idx<inode.metadata.size; idx++) {
|
||||
read_datablock(inode, idx, buffer);
|
||||
DirectoryEntry ent;
|
||||
for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){
|
||||
@ -275,9 +269,9 @@ int FilesOperation::fischl_mkdir(const char* path, mode_t mode) {
|
||||
}
|
||||
u_int64_t parent_inode_number = parent_filenode->inode_number;
|
||||
//make new inode
|
||||
INode* ret = create_new_inode(parent_inode_number, newDirname, mode|S_IFDIR);//specify S_IFDIR as directory
|
||||
INode_Data* ret = create_new_inode(parent_inode_number, newDirname, mode|S_IFDIR);//specify S_IFDIR as directory
|
||||
if (ret == NULL) return -1;//ENOSPC but create_new_inode handle ENAMETOOLONG EEXIST
|
||||
fischl_add_entry(parent_filenode->subdirectory, ret->block_number, newDirname, ret);
|
||||
fischl_add_entry(parent_filenode->subdirectory, ret->inode_num, newDirname, ret);
|
||||
delete pathdup;
|
||||
return 0;//SUCCESS
|
||||
}
|
||||
@ -300,10 +294,10 @@ int FilesOperation::fischl_mknod(const char* path, mode_t mode, dev_t dev) {
|
||||
}
|
||||
u_int64_t parent_inode_number = parent_filenode->inode_number;
|
||||
//make new inode
|
||||
INode* ret = create_new_inode(parent_inode_number, newFilename, mode);
|
||||
INode_Data* ret = create_new_inode(parent_inode_number, newFilename, mode);
|
||||
if (ret == NULL) return -1;//ENOSPC but create_new_inode handle ENAMETOOLONG EEXIST
|
||||
//make new node
|
||||
fischl_add_entry(parent_filenode->subdirectory, ret->block_number, newFilename, ret);
|
||||
fischl_add_entry(parent_filenode->subdirectory, ret->inode_num, newFilename, ret);
|
||||
delete pathdup;
|
||||
return 0;//SUCESS
|
||||
}
|
||||
@ -326,22 +320,23 @@ int FilesOperation::fischl_create(const char* path, mode_t mode, struct fuse_fil
|
||||
}
|
||||
u_int64_t parent_inode_number = parent_filenode->inode_number;
|
||||
//make new inode
|
||||
INode* ret = create_new_inode(parent_inode_number, newFilename, mode);
|
||||
INode_Data* ret = create_new_inode(parent_inode_number, newFilename, mode);
|
||||
if (ret == NULL) return -1;//ENOSPC but create_new_inode handle ENAMETOOLONG EEXIST
|
||||
//make new node in RAM
|
||||
fischl_add_entry(parent_filenode->subdirectory, ret->block_number, newFilename, ret);
|
||||
fischl_add_entry(parent_filenode->subdirectory, ret->inode_num, newFilename, ret);
|
||||
//directly give inode number rather than create file descriptor table
|
||||
fi->fh = ret->block_number;//assign file descriptor as inode number to fuse system
|
||||
fi->fh = ret->inode_num;//assign file descriptor as inode number to fuse system
|
||||
delete pathdup;
|
||||
return 0;//SUCESS
|
||||
}
|
||||
|
||||
void FilesOperation::unlink_inode(u_int64_t inode_number) {
|
||||
INode inode;
|
||||
inode.inode_construct(inode_number, disk);
|
||||
if ((inode.permissions & S_IFMT) == S_IFDIR) {
|
||||
INode_Data inode;
|
||||
inode.inode_num = inode_number;
|
||||
fs->inode_manager->load_inode(&inode);
|
||||
if ((inode.metadata.permissions & S_IFMT) == S_IFDIR) {
|
||||
char buffer[IO_BLOCK_SIZE] = {0};
|
||||
for(u_int64_t idx=0; idx<inode.size; idx++) {
|
||||
for(u_int64_t idx=0; idx<inode.metadata.size; idx++) {
|
||||
read_datablock(inode, idx, buffer);
|
||||
DirectoryEntry ent;
|
||||
for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){
|
||||
@ -351,11 +346,12 @@ void FilesOperation::unlink_inode(u_int64_t inode_number) {
|
||||
}
|
||||
}
|
||||
}
|
||||
while(inode.size != 0) {
|
||||
inode.datablock_deallocate(disk);
|
||||
inode.size--;
|
||||
while(inode.metadata.size != 0) {
|
||||
u_int64_t dummy;
|
||||
fs->deallocate_datablock(&inode, &dummy);
|
||||
inode.metadata.size--;
|
||||
}
|
||||
inop.inode_free(disk, inode_number);
|
||||
fs->inode_manager->free_inode(&inode);
|
||||
}
|
||||
|
||||
int FilesOperation::fischl_unlink(const char* path) {
|
||||
@ -378,10 +374,11 @@ int FilesOperation::fischl_unlink(const char* path) {
|
||||
u_int64_t target_inode = 0;
|
||||
|
||||
// remove its record from parent
|
||||
INode parent_INode;
|
||||
parent_INode.inode_construct(parent_inode_number, disk);
|
||||
INode_Data parent_INode;
|
||||
parent_INode.inode_num = parent_inode_number;
|
||||
fs->inode_manager->load_inode(&parent_INode);
|
||||
char rw_buffer[IO_BLOCK_SIZE] = {0};
|
||||
for (u_int64_t idx=0; idx<parent_INode.size; idx++) {
|
||||
for (u_int64_t idx=0; idx<parent_INode.metadata.size; idx++) {
|
||||
read_datablock(parent_INode, idx, rw_buffer);
|
||||
DirectoryEntry ent;
|
||||
for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){
|
||||
@ -468,10 +465,11 @@ int FilesOperation::fischl_read(const char *path, char *buf, size_t size, off_t
|
||||
*/
|
||||
// Caution! this based on content in file are multiple of IO_BLOCK_SIZE, not the exact write size.
|
||||
// based on current read_datablock API implement, when read_datablock pass with actual size not index this function should be fixed
|
||||
INode inode;
|
||||
INode_Data inode;
|
||||
// Assuming inode is correctly initialized here based on 'path'
|
||||
inode.inode_construct(fi->fh, disk);
|
||||
size_t len = inode.size * IO_BLOCK_SIZE; // Assuming each block is 4096 bytes
|
||||
inode.inode_num = fi->fh;
|
||||
fs->inode_manager->load_inode(&inode);
|
||||
size_t len = inode.metadata.size * IO_BLOCK_SIZE; // Assuming each block is 4096 bytes
|
||||
|
||||
if (offset >= len) return 0; // Offset is beyond the end of the file
|
||||
if (offset + size > len) size = len - offset; // Adjust size if it goes beyond EOF
|
||||
@ -479,8 +477,8 @@ int FilesOperation::fischl_read(const char *path, char *buf, size_t size, off_t
|
||||
size_t bytes_read = 0;
|
||||
size_t block_index = offset / IO_BLOCK_SIZE; // Starting block index
|
||||
size_t block_offset = offset % IO_BLOCK_SIZE; // Offset within the first block
|
||||
// fprintf(stderr,"[%s ,%d] inode.size %d\n",__func__,__LINE__, inode.size);
|
||||
while (bytes_read < size && block_index < inode.size) {
|
||||
// fprintf(stderr,"[%s ,%d] inode.metadata.size %d\n",__func__,__LINE__, inode.metadata.size);
|
||||
while (bytes_read < size && block_index < inode.metadata.size) {
|
||||
char block_buffer[IO_BLOCK_SIZE]; // Temporary buffer for each block
|
||||
read_datablock(inode, block_index, block_buffer);
|
||||
// fprintf(stderr,"[%s ,%d] block_index %d\n",__func__,__LINE__, block_index);
|
||||
|
@ -26,11 +26,23 @@ add_executable(${TARGET_LAYER1_API}
|
||||
)
|
||||
add_executable(${TARGET_LAYER2_API}
|
||||
../lib/direntry.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
|
||||
../lib/files.cpp
|
||||
layer2_API_dir.cpp
|
||||
)
|
||||
add_executable(${TARGET_DIR_API}
|
||||
../lib/direntry.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
|
||||
dir_API.cpp
|
||||
)
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <iostream>
|
||||
#include "fs.h"
|
||||
#include "fs.hpp"
|
||||
#include "direntry.h"
|
||||
|
||||
typedef struct file_test{
|
||||
@ -171,18 +171,18 @@ void traverseDirHierarchy(const dir_test* dir, int depth = 0) {
|
||||
|
||||
TEST(DirTest, root_test) {
|
||||
//Init fake root directory
|
||||
INode inode_root;
|
||||
INode_Data inode_root;
|
||||
u_int64_t file_permissions = 0;
|
||||
inode_root.permissions = file_permissions | S_IFDIR;
|
||||
inode_root.metadata.permissions = file_permissions | S_IFDIR;
|
||||
root = fischl_init_entry(0, mock_root->name, &inode_root);//0 is inode number assigned by inode_allocate()
|
||||
}
|
||||
TEST(DirTest, AddFile_test) {
|
||||
//assume file and dir itself(content,metadata) same,but different name and inode number
|
||||
INode inode_file;
|
||||
INode inode_dir;
|
||||
INode_Data inode_file;
|
||||
INode_Data inode_dir;
|
||||
u_int64_t file_permissions = 0;
|
||||
file_permissions = 0;
|
||||
inode_dir.permissions = file_permissions | S_IFDIR;
|
||||
inode_dir.metadata.permissions = file_permissions | S_IFDIR;
|
||||
fischl_add_entry(root, 2, mock_root->inFile->name,&inode_file);
|
||||
fischl_add_entry(root, 3, mock_root->subdir->name,&inode_dir);
|
||||
}
|
||||
@ -211,11 +211,11 @@ TEST(DirTest, FindFile_test) {
|
||||
}
|
||||
TEST(DirTest, Add_FindFile_test) {
|
||||
//add file and dir under subdirectory instead of root
|
||||
INode inode_file;
|
||||
INode inode_dir;
|
||||
INode_Data inode_file;
|
||||
INode_Data inode_dir;
|
||||
u_int64_t file_permissions = 0;
|
||||
file_permissions = 0;
|
||||
inode_dir.permissions = file_permissions | S_IFDIR;
|
||||
inode_dir.metadata.permissions = file_permissions | S_IFDIR;
|
||||
|
||||
/*add with subdirectory*/
|
||||
//Treenode dir(you cannot find here), you only can get Filenode dir based on fischl_find_entry Function
|
||||
@ -279,8 +279,8 @@ TEST(DirTest, Add_FindFile_test) {
|
||||
}
|
||||
|
||||
// TEST(DirTest, Scale_test){
|
||||
// INode inode_file;
|
||||
// INode inode_dir;
|
||||
// INode_Data inode_file;
|
||||
// INode_Data inode_dir;
|
||||
// u_int64_t file_permissions = 0;
|
||||
// file_permissions = 0;
|
||||
// inode_dir.permissions = file_permissions | S_IFDIR;
|
||||
|
@ -142,9 +142,3 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
d = (argc < 2) ? "/dev/vdc" : argv[1];//how to do with this?
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <iostream>
|
||||
#include "fs.hpp"
|
||||
#include "files.h"
|
||||
|
||||
|
||||
@ -27,6 +28,7 @@ void traverseDirHierarchy(const dir_test* dir, int depth);
|
||||
std::string target_filepath;
|
||||
dir_test* mock_root = nullptr;
|
||||
RawDisk *H;
|
||||
Fs *fs;
|
||||
FilesOperation *fsop;
|
||||
|
||||
int total_dir_num = 0;
|
||||
@ -37,6 +39,7 @@ int total_free_file = 0;
|
||||
TEST(FileOperationTest, MkdirnodTest) {
|
||||
|
||||
fsop->initialize_rootinode();
|
||||
printf("OK\n");
|
||||
struct fuse_file_info fi;
|
||||
|
||||
mode_t mode;//set mode
|
||||
@ -60,22 +63,24 @@ TEST(FileOperationTest, WriteTest) {
|
||||
// read and write to indirect datablocks are not supported yet
|
||||
//get inode info from disk
|
||||
char buffer[IO_BLOCK_SIZE] = {0};
|
||||
INode inode;
|
||||
INode_Data inode;
|
||||
u_int64_t get_disk_inum;
|
||||
//file test
|
||||
get_disk_inum = fsop->disk_namei("/test");
|
||||
inode.inode_construct(get_disk_inum, *H);
|
||||
inode.inode_num = get_disk_inum;
|
||||
fs->inode_manager->load_inode(&inode);
|
||||
buffer[0] = '1';
|
||||
fsop->write_datablock(inode, 0, buffer);
|
||||
inode.inode_save(*H);
|
||||
fs->inode_manager->save_inode(&inode);
|
||||
//other file baz
|
||||
get_disk_inum = fsop->disk_namei("/foo/bar/baz");
|
||||
inode.inode_construct(get_disk_inum, *H);
|
||||
inode.inode_num = get_disk_inum;
|
||||
fs->inode_manager->load_inode(&inode);
|
||||
buffer[0] = '4';
|
||||
fsop->write_datablock(inode, 3, buffer);
|
||||
buffer[0] = '5';
|
||||
fsop->write_datablock(inode, 101, buffer);
|
||||
inode.inode_save(*H);
|
||||
fs->inode_manager->save_inode(&inode);
|
||||
// TODO: guard against overwriting directory datablocks
|
||||
}
|
||||
|
||||
@ -117,12 +122,13 @@ TEST(FileOperationTest, RamDiskTest) {
|
||||
TEST(FileOperationTest, ReadTest) {
|
||||
// read files (TODO: fischl_read)
|
||||
char read_buffer[IO_BLOCK_SIZE] = {0};
|
||||
INode inode;
|
||||
INode_Data inode;
|
||||
u_int64_t get_file_inum;
|
||||
|
||||
//read test file
|
||||
get_file_inum = fsop->namei("/test");
|
||||
inode.inode_construct(get_file_inum, *H);
|
||||
inode.inode_num = get_file_inum;
|
||||
fs->inode_manager->load_inode(&inode);
|
||||
fsop->read_datablock(inode, 0, read_buffer);
|
||||
EXPECT_EQ(read_buffer[0], '1');
|
||||
|
||||
@ -135,7 +141,8 @@ TEST(FileOperationTest, ReadTest) {
|
||||
|
||||
//read baz file
|
||||
get_file_inum= fsop->namei("/foo/bar/baz");
|
||||
inode.inode_construct(get_file_inum, *H);
|
||||
inode.inode_num = get_file_inum;
|
||||
fs->inode_manager->load_inode(&inode);
|
||||
fsop->read_datablock(inode, 3, read_buffer);
|
||||
EXPECT_EQ(read_buffer[0], '4');
|
||||
fsop->read_datablock(inode, 101, read_buffer);
|
||||
@ -192,8 +199,10 @@ int main(int argc, char **argv) {
|
||||
const char* d = (argc < 2) ? "/dev/vdc" : argv[1];
|
||||
|
||||
setupTestDirectory(&mock_root);
|
||||
H = new RawDisk(d);
|
||||
fsop = new FilesOperation(*H);
|
||||
H = new FakeRawDisk(2048);
|
||||
fs = new Fs(H);
|
||||
fs->format();
|
||||
fsop = new FilesOperation(*H, fs);
|
||||
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
int result = RUN_ALL_TESTS();
|
||||
|
Loading…
x
Reference in New Issue
Block a user