pass layer2_API test, still need review
This commit is contained in:
parent
e56d304d2f
commit
e69527a10b
@ -11,9 +11,10 @@ class FilesOperation {
|
|||||||
public:
|
public:
|
||||||
TreeNode *root_node;
|
TreeNode *root_node;
|
||||||
FilesOperation(RawDisk&, Fs*);
|
FilesOperation(RawDisk&, Fs*);
|
||||||
int read_datablock(const INode_Data& inode, u_int64_t index, char* buffer);
|
//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);
|
//int write_datablock(INode_Data& inode, u_int64_t index, char* buffer);
|
||||||
void initialize_rootinode();
|
void initialize_rootinode();
|
||||||
|
void printbuffer(const char*,int);
|
||||||
void printDirectory(u_int64_t);
|
void printDirectory(u_int64_t);
|
||||||
INode_Data* 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);
|
void unlink_inode(u_int64_t inode_number);
|
||||||
|
@ -101,15 +101,6 @@ TreeNode *find_parentPath(TreeNode *root, const char *path) {
|
|||||||
void freeHashTable(HashTable *table) {
|
void freeHashTable(HashTable *table) {
|
||||||
if (table == NULL) return;
|
if (table == NULL) return;
|
||||||
|
|
||||||
for (int i = 0; i < table->size; ++i) {
|
|
||||||
FileNode *current = table->table[i];
|
|
||||||
while (current != NULL) {
|
|
||||||
FileNode *temp = current;
|
|
||||||
current = current->next;
|
|
||||||
// free(temp->name);
|
|
||||||
// free(temp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(table->table);
|
free(table->table);
|
||||||
free(table);
|
free(table);
|
||||||
}
|
}
|
||||||
|
131
lib/files.cpp
131
lib/files.cpp
@ -23,71 +23,17 @@ struct DirectoryEntry {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void FilesOperation::printbuffer(const char* buff, int len) {
|
||||||
|
for(int i=0;i<len;i++){
|
||||||
|
printf("%x ",buff[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
FilesOperation::FilesOperation(RawDisk& disk_, Fs* fs): disk(disk_) {
|
FilesOperation::FilesOperation(RawDisk& disk_, Fs* fs): disk(disk_) {
|
||||||
this->fs = fs;
|
this->fs = fs;
|
||||||
}
|
}
|
||||||
|
|
||||||
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.direct_blocks[index];
|
|
||||||
} else if (index < 48 + 512){
|
|
||||||
char indirect_buffer[IO_BLOCK_SIZE] = {0};
|
|
||||||
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.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.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_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;
|
|
||||||
}
|
|
||||||
//printf("Read %llu\n", read_offset/IO_BLOCK_SIZE);
|
|
||||||
return disk.read_block(read_offset/IO_BLOCK_SIZE, buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
int FilesOperation::write_datablock(INode_Data& inode, u_int64_t index, char* buffer) {
|
|
||||||
while (index >= inode.metadata.size) {
|
|
||||||
u_int64_t alloc_num;
|
|
||||||
int ret = (fs->allocate_datablock(&inode, &alloc_num));
|
|
||||||
printf("allocate_datablock returned %d\n",ret);
|
|
||||||
if (ret!=0) assert(false);
|
|
||||||
inode.metadata.size += 1;
|
|
||||||
}
|
|
||||||
u_int64_t write_offset = index_to_offset(inode, disk, index);
|
|
||||||
if (write_offset == (u_int64_t)(-1)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
//printf("Write %llu\n", write_offset/IO_BLOCK_SIZE);
|
|
||||||
return disk.write_block(write_offset/IO_BLOCK_SIZE, buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FilesOperation::create_dot_dotdot(INode_Data* inode, u_int64_t parent_inode_number) {
|
void FilesOperation::create_dot_dotdot(INode_Data* inode, u_int64_t parent_inode_number) {
|
||||||
char buffer[IO_BLOCK_SIZE] = {0};
|
char buffer[IO_BLOCK_SIZE] = {0};
|
||||||
DirectoryEntry dot;
|
DirectoryEntry dot;
|
||||||
@ -98,7 +44,8 @@ void FilesOperation::create_dot_dotdot(INode_Data* inode, u_int64_t parent_inode
|
|||||||
dotdot.inode_number = parent_inode_number;
|
dotdot.inode_number = parent_inode_number;
|
||||||
strcpy(dotdot.file_name, "..");
|
strcpy(dotdot.file_name, "..");
|
||||||
dotdot.serialize(buffer+264);
|
dotdot.serialize(buffer+264);
|
||||||
int ret = write_datablock(*inode, 0, buffer);
|
int ret = fs->write(inode, buffer, IO_BLOCK_SIZE, 0);
|
||||||
|
//printf("in create_dot_dotdot: fs->write returned %d\n",ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FilesOperation::initialize_rootinode() {
|
void FilesOperation::initialize_rootinode() {
|
||||||
@ -118,7 +65,7 @@ void FilesOperation::printDirectory(u_int64_t inode_number) {
|
|||||||
inode.inode_num = inode_number;
|
inode.inode_num = inode_number;
|
||||||
fs->inode_manager->load_inode(&inode);
|
fs->inode_manager->load_inode(&inode);
|
||||||
char buffer[IO_BLOCK_SIZE] = {0};
|
char buffer[IO_BLOCK_SIZE] = {0};
|
||||||
read_datablock(inode, 0, buffer);
|
fs->read(&inode, buffer, IO_BLOCK_SIZE, 0);
|
||||||
DirectoryEntry ent;
|
DirectoryEntry ent;
|
||||||
for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){
|
for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){
|
||||||
ent.deserialize(buffer+i);
|
ent.deserialize(buffer+i);
|
||||||
@ -143,8 +90,8 @@ INode_Data* FilesOperation::create_new_inode(u_int64_t parent_inode_number, cons
|
|||||||
|
|
||||||
// Check if file or directory already exists
|
// Check if file or directory already exists
|
||||||
char r_buffer[IO_BLOCK_SIZE] = {0};
|
char r_buffer[IO_BLOCK_SIZE] = {0};
|
||||||
for (u_int64_t idx=0; idx<inode.metadata.size; idx++) {
|
for (u_int64_t idx=0; idx<inode.metadata.size/IO_BLOCK_SIZE; idx++) {
|
||||||
read_datablock(inode, idx, r_buffer);
|
fs->read(&inode, r_buffer, IO_BLOCK_SIZE, idx*IO_BLOCK_SIZE);
|
||||||
DirectoryEntry ent;
|
DirectoryEntry ent;
|
||||||
for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){
|
for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){
|
||||||
ent.deserialize(r_buffer+i);
|
ent.deserialize(r_buffer+i);
|
||||||
@ -164,11 +111,12 @@ INode_Data* FilesOperation::create_new_inode(u_int64_t parent_inode_number, cons
|
|||||||
fs->inode_manager->new_inode(0, 0, mode, new_inode);
|
fs->inode_manager->new_inode(0, 0, mode, new_inode);
|
||||||
if ((mode & S_IFMT) == S_IFDIR) {
|
if ((mode & S_IFMT) == S_IFDIR) {
|
||||||
create_dot_dotdot(new_inode, parent_inode_number);
|
create_dot_dotdot(new_inode, parent_inode_number);
|
||||||
|
fs->inode_manager->save_inode(new_inode);
|
||||||
}
|
}
|
||||||
|
|
||||||
char rw_buffer[IO_BLOCK_SIZE] = {0};
|
char rw_buffer[IO_BLOCK_SIZE] = {0};
|
||||||
for (u_int64_t idx=0; idx<inode.metadata.size; idx++) {
|
for (u_int64_t idx=0; idx<inode.metadata.size/IO_BLOCK_SIZE; idx++) {
|
||||||
read_datablock(inode, idx, rw_buffer);
|
fs->read(&inode, rw_buffer, IO_BLOCK_SIZE, idx*IO_BLOCK_SIZE);
|
||||||
DirectoryEntry ent;
|
DirectoryEntry ent;
|
||||||
for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){
|
for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){
|
||||||
ent.deserialize(rw_buffer+i);
|
ent.deserialize(rw_buffer+i);
|
||||||
@ -181,7 +129,7 @@ INode_Data* FilesOperation::create_new_inode(u_int64_t parent_inode_number, cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (allocated) {
|
if (allocated) {
|
||||||
write_datablock(inode, idx, rw_buffer);
|
fs->write(&inode, rw_buffer, IO_BLOCK_SIZE, idx*IO_BLOCK_SIZE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -192,7 +140,7 @@ INode_Data* FilesOperation::create_new_inode(u_int64_t parent_inode_number, cons
|
|||||||
ent.inode_number = new_inode->inode_num;
|
ent.inode_number = new_inode->inode_num;
|
||||||
strcpy(ent.file_name, name);
|
strcpy(ent.file_name, name);
|
||||||
ent.serialize(write_buffer);
|
ent.serialize(write_buffer);
|
||||||
write_datablock(inode, inode.metadata.size, write_buffer);
|
fs->write(&inode, write_buffer, IO_BLOCK_SIZE, (inode.metadata.size/IO_BLOCK_SIZE)*IO_BLOCK_SIZE);
|
||||||
fs->inode_manager->save_inode(&inode);
|
fs->inode_manager->save_inode(&inode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,8 +169,8 @@ u_int64_t FilesOperation::disk_namei(const char* path) {
|
|||||||
u_int64_t new_inode_number = 0;
|
u_int64_t new_inode_number = 0;
|
||||||
|
|
||||||
char buffer[IO_BLOCK_SIZE] = {0};
|
char buffer[IO_BLOCK_SIZE] = {0};
|
||||||
for(u_int64_t idx=0; idx<inode.metadata.size; idx++) {
|
for(u_int64_t idx=0; idx<inode.metadata.size/IO_BLOCK_SIZE; idx++) {
|
||||||
read_datablock(inode, idx, buffer);
|
fs->read(&inode, buffer, IO_BLOCK_SIZE, idx*IO_BLOCK_SIZE);
|
||||||
DirectoryEntry ent;
|
DirectoryEntry ent;
|
||||||
for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){
|
for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){
|
||||||
ent.deserialize(buffer+i);
|
ent.deserialize(buffer+i);
|
||||||
@ -265,7 +213,7 @@ int FilesOperation::fischl_mkdir(const char* path, mode_t mode) {
|
|||||||
FileNode *parent_filenode = strlen(ParentPath)? fischl_find_entry(root_node, ParentPath): root_node->self_info;
|
FileNode *parent_filenode = strlen(ParentPath)? fischl_find_entry(root_node, ParentPath): root_node->self_info;
|
||||||
if (parent_filenode == NULL) {
|
if (parent_filenode == NULL) {
|
||||||
fprintf(stderr,"[%s ,%d] ParentPath:{%s} not found\n",__func__,__LINE__, ParentPath);
|
fprintf(stderr,"[%s ,%d] ParentPath:{%s} not found\n",__func__,__LINE__, ParentPath);
|
||||||
delete pathdup;
|
free(pathdup);
|
||||||
return -ENOENT;//parentpath directory does not exist
|
return -ENOENT;//parentpath directory does not exist
|
||||||
}
|
}
|
||||||
u_int64_t parent_inode_number = parent_filenode->inode_number;
|
u_int64_t parent_inode_number = parent_filenode->inode_number;
|
||||||
@ -274,7 +222,7 @@ int FilesOperation::fischl_mkdir(const char* path, mode_t mode) {
|
|||||||
INode_Data* 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
|
if (ret == NULL) return -1;//ENOSPC but create_new_inode handle ENAMETOOLONG EEXIST
|
||||||
fischl_add_entry(parent_filenode->subdirectory, ret->inode_num, newDirname, ret);
|
fischl_add_entry(parent_filenode->subdirectory, ret->inode_num, newDirname, ret);
|
||||||
delete pathdup;
|
free(pathdup);
|
||||||
return 0;//SUCCESS
|
return 0;//SUCCESS
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -291,7 +239,7 @@ int FilesOperation::fischl_mknod(const char* path, mode_t mode, dev_t dev) {
|
|||||||
FileNode *parent_filenode = strlen(ParentPath)? fischl_find_entry(root_node, ParentPath): root_node->self_info;
|
FileNode *parent_filenode = strlen(ParentPath)? fischl_find_entry(root_node, ParentPath): root_node->self_info;
|
||||||
if (parent_filenode == NULL) {
|
if (parent_filenode == NULL) {
|
||||||
fprintf(stderr,"[%s ,%d] ParentPath:{%s} not found\n",__func__,__LINE__, ParentPath);
|
fprintf(stderr,"[%s ,%d] ParentPath:{%s} not found\n",__func__,__LINE__, ParentPath);
|
||||||
delete pathdup;
|
free(pathdup);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
u_int64_t parent_inode_number = parent_filenode->inode_number;
|
u_int64_t parent_inode_number = parent_filenode->inode_number;
|
||||||
@ -300,7 +248,7 @@ int FilesOperation::fischl_mknod(const char* path, mode_t mode, dev_t dev) {
|
|||||||
if (ret == NULL) return -1;//ENOSPC but create_new_inode handle ENAMETOOLONG EEXIST
|
if (ret == NULL) return -1;//ENOSPC but create_new_inode handle ENAMETOOLONG EEXIST
|
||||||
//make new node
|
//make new node
|
||||||
fischl_add_entry(parent_filenode->subdirectory, ret->inode_num, newFilename, ret);
|
fischl_add_entry(parent_filenode->subdirectory, ret->inode_num, newFilename, ret);
|
||||||
delete pathdup;
|
free(pathdup);
|
||||||
return 0;//SUCESS
|
return 0;//SUCESS
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -317,7 +265,7 @@ int FilesOperation::fischl_create(const char* path, mode_t mode, struct fuse_fil
|
|||||||
FileNode *parent_filenode = strlen(ParentPath)? fischl_find_entry(root_node, ParentPath): root_node->self_info;
|
FileNode *parent_filenode = strlen(ParentPath)? fischl_find_entry(root_node, ParentPath): root_node->self_info;
|
||||||
if (parent_filenode == NULL) {
|
if (parent_filenode == NULL) {
|
||||||
fprintf(stderr,"[%s ,%d] ParentPath:{%s} not found\n",__func__,__LINE__, ParentPath);
|
fprintf(stderr,"[%s ,%d] ParentPath:{%s} not found\n",__func__,__LINE__, ParentPath);
|
||||||
delete pathdup;
|
free(pathdup);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
u_int64_t parent_inode_number = parent_filenode->inode_number;
|
u_int64_t parent_inode_number = parent_filenode->inode_number;
|
||||||
@ -328,7 +276,7 @@ int FilesOperation::fischl_create(const char* path, mode_t mode, struct fuse_fil
|
|||||||
fischl_add_entry(parent_filenode->subdirectory, ret->inode_num, newFilename, ret);
|
fischl_add_entry(parent_filenode->subdirectory, ret->inode_num, newFilename, ret);
|
||||||
//directly give inode number rather than create file descriptor table
|
//directly give inode number rather than create file descriptor table
|
||||||
fi->fh = ret->inode_num;//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;
|
free(pathdup);
|
||||||
return 0;//SUCESS
|
return 0;//SUCESS
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,8 +286,8 @@ void FilesOperation::unlink_inode(u_int64_t inode_number) {
|
|||||||
fs->inode_manager->load_inode(&inode);
|
fs->inode_manager->load_inode(&inode);
|
||||||
if ((inode.metadata.permissions & S_IFMT) == S_IFDIR) {
|
if ((inode.metadata.permissions & S_IFMT) == S_IFDIR) {
|
||||||
char buffer[IO_BLOCK_SIZE] = {0};
|
char buffer[IO_BLOCK_SIZE] = {0};
|
||||||
for(u_int64_t idx=0; idx<inode.metadata.size; idx++) {
|
for(u_int64_t idx=0; idx<inode.metadata.size/IO_BLOCK_SIZE; idx++) {
|
||||||
read_datablock(inode, idx, buffer);
|
fs->read(&inode, buffer, IO_BLOCK_SIZE, idx*IO_BLOCK_SIZE);
|
||||||
DirectoryEntry ent;
|
DirectoryEntry ent;
|
||||||
for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){
|
for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){
|
||||||
if(ent.inode_number && strcmp(ent.file_name,".") && strcmp(ent.file_name,"..")){
|
if(ent.inode_number && strcmp(ent.file_name,".") && strcmp(ent.file_name,"..")){
|
||||||
@ -348,10 +296,11 @@ void FilesOperation::unlink_inode(u_int64_t inode_number) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// TODO: This is probably incorrect
|
||||||
while(inode.metadata.size != 0) {
|
while(inode.metadata.size != 0) {
|
||||||
u_int64_t dummy;
|
u_int64_t dummy;
|
||||||
fs->deallocate_datablock(&inode, &dummy);
|
fs->deallocate_datablock(&inode, &dummy);
|
||||||
inode.metadata.size--;
|
inode.metadata.size-=IO_BLOCK_SIZE;
|
||||||
}
|
}
|
||||||
fs->inode_manager->free_inode(&inode);
|
fs->inode_manager->free_inode(&inode);
|
||||||
}
|
}
|
||||||
@ -369,7 +318,7 @@ int FilesOperation::fischl_unlink(const char* path) {
|
|||||||
FileNode *parent_filenode = fischl_find_entry(root_node, ParentPath);
|
FileNode *parent_filenode = fischl_find_entry(root_node, ParentPath);
|
||||||
if (parent_filenode == NULL) {
|
if (parent_filenode == NULL) {
|
||||||
printf("parent %s not found by fischl_find_entry\n", ParentPath);
|
printf("parent %s not found by fischl_find_entry\n", ParentPath);
|
||||||
delete pathdup;
|
free(pathdup);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
u_int64_t parent_inode_number = parent_filenode->inode_number;
|
u_int64_t parent_inode_number = parent_filenode->inode_number;
|
||||||
@ -380,8 +329,8 @@ int FilesOperation::fischl_unlink(const char* path) {
|
|||||||
parent_INode.inode_num = parent_inode_number;
|
parent_INode.inode_num = parent_inode_number;
|
||||||
fs->inode_manager->load_inode(&parent_INode);
|
fs->inode_manager->load_inode(&parent_INode);
|
||||||
char rw_buffer[IO_BLOCK_SIZE] = {0};
|
char rw_buffer[IO_BLOCK_SIZE] = {0};
|
||||||
for (u_int64_t idx=0; idx<parent_INode.metadata.size; idx++) {
|
for (u_int64_t idx=0; idx<parent_INode.metadata.size/IO_BLOCK_SIZE; idx++) {
|
||||||
read_datablock(parent_INode, idx, rw_buffer);
|
fs->read(&parent_INode, rw_buffer, IO_BLOCK_SIZE, idx*IO_BLOCK_SIZE);
|
||||||
DirectoryEntry ent;
|
DirectoryEntry ent;
|
||||||
for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){
|
for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){
|
||||||
ent.deserialize(rw_buffer+i);
|
ent.deserialize(rw_buffer+i);
|
||||||
@ -393,7 +342,7 @@ int FilesOperation::fischl_unlink(const char* path) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (target_inode) {
|
if (target_inode) {
|
||||||
write_datablock(parent_INode, idx, rw_buffer);
|
fs->write(&parent_INode, rw_buffer, IO_BLOCK_SIZE, idx*IO_BLOCK_SIZE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -403,11 +352,11 @@ int FilesOperation::fischl_unlink(const char* path) {
|
|||||||
unlink_inode(target_inode);
|
unlink_inode(target_inode);
|
||||||
// remove node itself and from parent hash
|
// remove node itself and from parent hash
|
||||||
fischl_rm_entry(parent_filenode->subdirectory, filename);
|
fischl_rm_entry(parent_filenode->subdirectory, filename);
|
||||||
delete pathdup;
|
free(pathdup);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
printf("cannot find %s in %s", filename, ParentPath);
|
printf("cannot find %s in %s", filename, ParentPath);
|
||||||
delete pathdup;
|
free(pathdup);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -457,7 +406,7 @@ int FilesOperation::fischl_write(const char *path, const char *buf, size_t size,
|
|||||||
// Assuming inode is correctly initialized here based on 'path'
|
// Assuming inode is correctly initialized here based on 'path'
|
||||||
inode.inode_num = fi->fh;
|
inode.inode_num = fi->fh;
|
||||||
fs->inode_manager->load_inode(&inode);
|
fs->inode_manager->load_inode(&inode);
|
||||||
size_t len = inode.metadata.size * IO_BLOCK_SIZE; // Assuming each block is 4096 bytes
|
size_t len = (inode.metadata.size/IO_BLOCK_SIZE) * IO_BLOCK_SIZE; // Assuming each block is 4096 bytes
|
||||||
|
|
||||||
size_t bytes_write = 0;
|
size_t bytes_write = 0;
|
||||||
size_t block_index = offset / IO_BLOCK_SIZE; // Starting block index
|
size_t block_index = offset / IO_BLOCK_SIZE; // Starting block index
|
||||||
@ -466,7 +415,7 @@ int FilesOperation::fischl_write(const char *path, const char *buf, size_t size,
|
|||||||
char block_buffer[IO_BLOCK_SIZE]; // Temporary buffer for each block
|
char block_buffer[IO_BLOCK_SIZE]; // Temporary buffer for each block
|
||||||
size_t copy_size = std::min(size - bytes_write, IO_BLOCK_SIZE - block_offset);
|
size_t copy_size = std::min(size - bytes_write, IO_BLOCK_SIZE - block_offset);
|
||||||
memcpy(block_buffer + block_offset, buf + bytes_write, copy_size);
|
memcpy(block_buffer + block_offset, buf + bytes_write, copy_size);
|
||||||
write_datablock(inode, block_index, block_buffer);
|
fs->write(&inode, block_buffer, IO_BLOCK_SIZE, block_index*IO_BLOCK_SIZE);
|
||||||
// fprintf(stderr,"[%s ,%d] inode.size %d, block_index %d, block_buffer %s\n",__func__,__LINE__, inode.size, block_index, block_buffer);
|
// fprintf(stderr,"[%s ,%d] inode.size %d, block_index %d, block_buffer %s\n",__func__,__LINE__, inode.size, block_index, block_buffer);
|
||||||
bytes_write += copy_size;
|
bytes_write += copy_size;
|
||||||
block_index++;
|
block_index++;
|
||||||
@ -492,7 +441,7 @@ int FilesOperation::fischl_read(const char *path, char *buf, size_t size, off_t
|
|||||||
// Assuming inode is correctly initialized here based on 'path'
|
// Assuming inode is correctly initialized here based on 'path'
|
||||||
inode.inode_num = fi->fh;
|
inode.inode_num = fi->fh;
|
||||||
fs->inode_manager->load_inode(&inode);
|
fs->inode_manager->load_inode(&inode);
|
||||||
size_t len = inode.metadata.size * IO_BLOCK_SIZE; // Assuming each block is 4096 bytes
|
size_t len = (inode.metadata.size/IO_BLOCK_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 >= 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
|
if (offset + size > len) size = len - offset; // Adjust size if it goes beyond EOF
|
||||||
@ -501,9 +450,9 @@ int FilesOperation::fischl_read(const char *path, char *buf, size_t size, off_t
|
|||||||
size_t block_index = offset / IO_BLOCK_SIZE; // Starting block index
|
size_t block_index = offset / IO_BLOCK_SIZE; // Starting block index
|
||||||
size_t block_offset = offset % IO_BLOCK_SIZE; // Offset within the first block
|
size_t block_offset = offset % IO_BLOCK_SIZE; // Offset within the first block
|
||||||
// fprintf(stderr,"[%s ,%d] inode.metadata.size %d\n",__func__,__LINE__, inode.metadata.size);
|
// fprintf(stderr,"[%s ,%d] inode.metadata.size %d\n",__func__,__LINE__, inode.metadata.size);
|
||||||
while (bytes_read < size && block_index < inode.metadata.size) {
|
while (bytes_read < size && block_index < inode.metadata.size/IO_BLOCK_SIZE) {
|
||||||
char block_buffer[IO_BLOCK_SIZE]; // Temporary buffer for each block
|
char block_buffer[IO_BLOCK_SIZE]; // Temporary buffer for each block
|
||||||
read_datablock(inode, block_index, block_buffer);
|
fs->read(&inode, block_buffer, IO_BLOCK_SIZE, block_index*IO_BLOCK_SIZE);
|
||||||
// fprintf(stderr,"[%s ,%d] block_index %d\n",__func__,__LINE__, block_index);
|
// fprintf(stderr,"[%s ,%d] block_index %d\n",__func__,__LINE__, block_index);
|
||||||
size_t copy_size = std::min(size - bytes_read, IO_BLOCK_SIZE - block_offset);
|
size_t copy_size = std::min(size - bytes_read, IO_BLOCK_SIZE - block_offset);
|
||||||
memcpy(buf + bytes_read, block_buffer + block_offset, copy_size);
|
memcpy(buf + bytes_read, block_buffer + block_offset, copy_size);
|
||||||
|
@ -3,6 +3,7 @@ set(TARGET_LAYER1_API test_layer1_API)
|
|||||||
set(TARGET_LAYER2_API test_layer2_API)
|
set(TARGET_LAYER2_API test_layer2_API)
|
||||||
set(TARGET_DIR_API test_dir_API)
|
set(TARGET_DIR_API test_dir_API)
|
||||||
set(DIR_PLACE /dev/vdb)
|
set(DIR_PLACE /dev/vdb)
|
||||||
|
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fsanitize=address")
|
||||||
|
|
||||||
# add test sources here ...
|
# add test sources here ...
|
||||||
add_executable(${TARGET_LAYER0}
|
add_executable(${TARGET_LAYER0}
|
||||||
@ -21,6 +22,7 @@ add_executable(${TARGET_LAYER1_API}
|
|||||||
../lib/fs/datablock_manager.cpp
|
../lib/fs/datablock_manager.cpp
|
||||||
../lib/fs/fs_data_types.cpp
|
../lib/fs/fs_data_types.cpp
|
||||||
../lib/fs/fs_resize.cpp
|
../lib/fs/fs_resize.cpp
|
||||||
|
../lib/fs/fs_read_write.cpp
|
||||||
../lib/fs/fs.cpp
|
../lib/fs/fs.cpp
|
||||||
../lib/fs/inode_manager.cpp
|
../lib/fs/inode_manager.cpp
|
||||||
)
|
)
|
||||||
@ -30,6 +32,7 @@ add_executable(${TARGET_LAYER2_API}
|
|||||||
../lib/fs/datablock_manager.cpp
|
../lib/fs/datablock_manager.cpp
|
||||||
../lib/fs/fs_data_types.cpp
|
../lib/fs/fs_data_types.cpp
|
||||||
../lib/fs/fs_resize.cpp
|
../lib/fs/fs_resize.cpp
|
||||||
|
../lib/fs/fs_read_write.cpp
|
||||||
../lib/fs/fs.cpp
|
../lib/fs/fs.cpp
|
||||||
../lib/fs/inode_manager.cpp
|
../lib/fs/inode_manager.cpp
|
||||||
../lib/files.cpp
|
../lib/files.cpp
|
||||||
@ -41,6 +44,7 @@ add_executable(${TARGET_DIR_API}
|
|||||||
../lib/fs/datablock_manager.cpp
|
../lib/fs/datablock_manager.cpp
|
||||||
../lib/fs/fs_data_types.cpp
|
../lib/fs/fs_data_types.cpp
|
||||||
../lib/fs/fs_resize.cpp
|
../lib/fs/fs_resize.cpp
|
||||||
|
../lib/fs/fs_read_write.cpp
|
||||||
../lib/fs/fs.cpp
|
../lib/fs/fs.cpp
|
||||||
../lib/fs/inode_manager.cpp
|
../lib/fs/inode_manager.cpp
|
||||||
dir_API.cpp
|
dir_API.cpp
|
||||||
|
@ -133,7 +133,7 @@ int main(int argc, char *argv[]) {
|
|||||||
for (int j = 0; j < 3; j++) {
|
for (int j = 0; j < 3; j++) {
|
||||||
fs->allocate_datablock(&inode_list[i], &temp_block_num);
|
fs->allocate_datablock(&inode_list[i], &temp_block_num);
|
||||||
//assert(temp_block_num == rec_datablock_free[i][j]);
|
//assert(temp_block_num == rec_datablock_free[i][j]);
|
||||||
printf("%llu," ,itemp_block_num);
|
printf("%llu," ,temp_block_num);
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ void traverseDirHierarchy(const dir_test* dir, int depth);
|
|||||||
//global can be taken
|
//global can be taken
|
||||||
std::string target_filepath;
|
std::string target_filepath;
|
||||||
dir_test* mock_root = nullptr;
|
dir_test* mock_root = nullptr;
|
||||||
RawDisk *H;
|
RawDisk *H; // Use FakeRawDisk here if memory sanitizer complains
|
||||||
Fs *fs;
|
Fs *fs;
|
||||||
FilesOperation *fsop;
|
FilesOperation *fsop;
|
||||||
|
|
||||||
@ -45,15 +45,11 @@ TEST(FileOperationTest, MkdirnodTest) {
|
|||||||
mode = S_IRWXU | S_IRWXG | S_IRWXO;//future should test permission
|
mode = S_IRWXU | S_IRWXG | S_IRWXO;//future should test permission
|
||||||
//S_IRWXU(S_IRUSR | S_IWUSR | S_IXUSR) (owner), S_IRWXG(S_IRGRP | S_IWGRP | S_IXGRP) (group), S_IRWXO(S_IROTH | S_IWOTH | S_IXOTH)
|
//S_IRWXU(S_IRUSR | S_IWUSR | S_IXUSR) (owner), S_IRWXG(S_IRGRP | S_IWGRP | S_IXGRP) (group), S_IRWXO(S_IROTH | S_IWOTH | S_IXOTH)
|
||||||
EXPECT_EQ(fsop->fischl_create("/test", mode, &fi), 0);
|
EXPECT_EQ(fsop->fischl_create("/test", mode, &fi), 0);
|
||||||
printf("point 1:");
|
|
||||||
fsop->printDirectory(1);
|
|
||||||
EXPECT_EQ(fsop->fischl_mkdir("/foo", mode), 0);
|
EXPECT_EQ(fsop->fischl_mkdir("/foo", mode), 0);
|
||||||
printf("point 2:");
|
|
||||||
fsop->printDirectory(1);
|
|
||||||
EXPECT_EQ(fsop->fischl_mkdir("/foo/bar", mode),0);
|
EXPECT_EQ(fsop->fischl_mkdir("/foo/bar", mode),0);
|
||||||
printf("point 3:");
|
|
||||||
fsop->printDirectory(1);
|
fsop->printDirectory(1);
|
||||||
EXPECT_EQ(fsop->fischl_create("/foo/bar/baz", mode, &fi), 0);
|
EXPECT_EQ(fsop->fischl_create("/foo/bar/baz", mode, &fi), 0);
|
||||||
|
fsop->printDirectory(4);
|
||||||
// the following three testcases will fail
|
// the following three testcases will fail
|
||||||
printf("Failing cases\n");
|
printf("Failing cases\n");
|
||||||
EXPECT_TRUE(fsop->fischl_mkdir("foo/bar", mode) < 0);
|
EXPECT_TRUE(fsop->fischl_mkdir("foo/bar", mode) < 0);
|
||||||
@ -74,11 +70,14 @@ TEST(FileOperationTest, WriteTest) {
|
|||||||
struct fuse_file_info fi;
|
struct fuse_file_info fi;
|
||||||
|
|
||||||
//file test
|
//file test
|
||||||
|
printf("point 0\n");
|
||||||
get_disk_inum = fsop->disk_namei("/test");
|
get_disk_inum = fsop->disk_namei("/test");
|
||||||
|
printf("point 1\n");
|
||||||
fsop->fischl_open("/test", &fi);
|
fsop->fischl_open("/test", &fi);
|
||||||
EXPECT_EQ(fi.fh, get_disk_inum);
|
EXPECT_EQ(fi.fh, get_disk_inum);
|
||||||
buffer[0] = '1';
|
buffer[0] = '1';
|
||||||
fsop->fischl_write("/test", buffer, sizeof(buffer), 0, &fi);
|
fsop->fischl_write("/test", buffer, sizeof(buffer), 0, &fi);
|
||||||
|
printf("point 2\n");
|
||||||
//other file baz
|
//other file baz
|
||||||
get_disk_inum = fsop->disk_namei("/foo/bar/baz");
|
get_disk_inum = fsop->disk_namei("/foo/bar/baz");
|
||||||
buffer[0] = '4';
|
buffer[0] = '4';
|
||||||
@ -134,8 +133,8 @@ TEST(FileOperationTest, ReadTest) {
|
|||||||
get_file_inum = fsop->namei("/test");
|
get_file_inum = fsop->namei("/test");
|
||||||
inode.inode_num = get_file_inum;
|
inode.inode_num = get_file_inum;
|
||||||
fs->inode_manager->load_inode(&inode);
|
fs->inode_manager->load_inode(&inode);
|
||||||
fsop->read_datablock(inode, 0, read_buffer);
|
//fsop->read_datablock(inode, 0, read_buffer);
|
||||||
EXPECT_EQ(read_buffer[0], '1');
|
//EXPECT_EQ(read_buffer[0], '1');
|
||||||
|
|
||||||
//read test file again with fischl_read API
|
//read test file again with fischl_read API
|
||||||
struct fuse_file_info fi;
|
struct fuse_file_info fi;
|
||||||
@ -165,12 +164,14 @@ TEST(FileOperationTest, PressureTest) {
|
|||||||
mode_t mode;//set mode
|
mode_t mode;//set mode
|
||||||
mode = S_IRWXU | S_IRWXG | S_IRWXO;//future should test permission
|
mode = S_IRWXU | S_IRWXG | S_IRWXO;//future should test permission
|
||||||
EXPECT_EQ(fsop->fischl_mkdir("/pressure", mode), 0);
|
EXPECT_EQ(fsop->fischl_mkdir("/pressure", mode), 0);
|
||||||
|
fsop->printDirectory(1);
|
||||||
|
|
||||||
u_int64_t inode_numbers[700];
|
u_int64_t inode_numbers[700];
|
||||||
std::string prefix = "/pressure/No_";
|
std::string prefix = "/pressure/No_";
|
||||||
for(int i=0;i<700;i++){
|
for(int i=0;i<700;i++){
|
||||||
EXPECT_EQ(fsop->fischl_mkdir((prefix+std::to_string(i)).c_str(), mode), 0);
|
EXPECT_EQ(fsop->fischl_mkdir((prefix+std::to_string(i)).c_str(), mode), 0);
|
||||||
}
|
}
|
||||||
|
fsop->printDirectory(6);
|
||||||
for(int i=0;i<700;i++){
|
for(int i=0;i<700;i++){
|
||||||
EXPECT_EQ(fsop->namei((prefix+std::to_string(i)).c_str()),fsop->disk_namei((prefix+std::to_string(i)).c_str()));
|
EXPECT_EQ(fsop->namei((prefix+std::to_string(i)).c_str()),fsop->disk_namei((prefix+std::to_string(i)).c_str()));
|
||||||
}
|
}
|
||||||
@ -211,7 +212,7 @@ int main(int argc, char **argv) {
|
|||||||
const char* d = (argc < 2) ? "/dev/vdc" : argv[1];
|
const char* d = (argc < 2) ? "/dev/vdc" : argv[1];
|
||||||
|
|
||||||
setupTestDirectory(&mock_root);
|
setupTestDirectory(&mock_root);
|
||||||
H = new FakeRawDisk(2048);
|
H = new FakeRawDisk(21504);
|
||||||
fs = new Fs(H);
|
fs = new Fs(H);
|
||||||
fs->format();
|
fs->format();
|
||||||
fsop = new FilesOperation(*H, fs);
|
fsop = new FilesOperation(*H, fs);
|
||||||
@ -299,7 +300,9 @@ dir_test* createDirHierarchy(int level, int maxLevel) {
|
|||||||
void setupTestDirectory(dir_test** root) {
|
void setupTestDirectory(dir_test** root) {
|
||||||
// Allocate memory for root
|
// Allocate memory for root
|
||||||
*root = new dir_test;
|
*root = new dir_test;
|
||||||
(*root)->name = strdup("/"); // use / as begin
|
char* root_name = new char[2];
|
||||||
|
strcpy(root_name, "/");
|
||||||
|
(*root)->name = root_name; // use / as begin
|
||||||
(*root)->inFile = nullptr; // Initialize file list to nullptr
|
(*root)->inFile = nullptr; // Initialize file list to nullptr
|
||||||
(*root)->subdir = createDirHierarchy(0, 1);
|
(*root)->subdir = createDirHierarchy(0, 1);
|
||||||
(*root)->next = nullptr;
|
(*root)->next = nullptr;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user