fixed a load entry bug

This commit is contained in:
FactorialN 2023-12-02 23:18:51 -08:00
parent 2838295f4d
commit 81ad41f8f2
4 changed files with 54 additions and 70 deletions

View File

@ -19,6 +19,7 @@ typedef struct treeNode {
FileNode *self_info; //self fileNode infromation
} TreeNode;
/*
typedef struct RenameInfo {
FileNode *oldFileNode; // The file node being renamed.
FileNode *oldParentNode; // The parent directory of the file node being renamed.
@ -26,7 +27,7 @@ typedef struct RenameInfo {
char *newName; // The new name of the file node after the rename.
FileNode *newFileNode; // The new file node, if one already exists at the target location.
bool exchangeExist; // Flag to indicate if the rename should replace an existing file node.
} RenameInfo;
} RenameInfo;*/
/*for root*/
TreeNode *fischl_init_entry(int new_inode_number, const char *fileName, INode_Data *new_inode);

View File

@ -247,7 +247,8 @@ FileNode *fischl_find_entry(Fs *fs, TreeNode *root, const char *path){
DirectoryEntry ent;
for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){
ent.deserialize(buffer+i);
if (ent.inode_number && strcmp(ent.file_name, segment)) {
//printf("WARNING:%d %llu %llu %s %s\n",__LINE__,inode.inode_num, ent.inode_number, ent.file_name, segment);
if (ent.inode_number && strcmp(ent.file_name, segment)==0) {
if(fischl_add_entry_for_cache(current, ent.inode_number, ent.file_name, &inode, file)<0){
return NULL;
}

View File

@ -776,103 +776,85 @@ int FilesOperation::fischl_link(const char* from, const char* to){
// TODO: rename dir and rename fail
int FilesOperation::fischl_rename(const char *old_path, const char *new_path, unsigned int flags){
//find old path
char *pathdup = strdup(old_path);
int FilesOperation::fischl_rename(const char *path, const char *new_name, unsigned int flags){
char *pathdup = strdup(path);
char *lastSlash = strrchr(pathdup, '/');
*lastSlash = '\0';
char *filename = lastSlash+1;
char *oldParentPath = pathdup;
char *ParentPath = pathdup;
if (!strcmp(filename,".")||!strcmp(filename,"..")) {
printf("refuse to remove . or ..\n");
printf("refusing to remove . or ..\n");
return -1;
}
//put old path info in rename struct
RenameInfo rename_info;
rename_info.exchangeExist = false;
rename_info.oldParentNode = fischl_load_entry(root_node, oldParentPath);
rename_info.oldFileNode = fischl_load_entry(rename_info.oldParentNode->subdirectory, filename);
if (rename_info.oldFileNode == NULL) {
printf("path %s not found by fischl_load_entry\n", old_path);
FileNode *parent_filenode = fischl_load_entry(root_node, ParentPath);
if (parent_filenode == NULL) {
printf("parent %s not found by fischl_load_entry\n", ParentPath);
free(pathdup);
return -1;
}
//find new path
char *new_pathdup = strdup(new_path);
lastSlash = strrchr(new_pathdup, '/');
*lastSlash = '\0'; // Split the string into parent path and new directory name; <parent path>\0<direcotry name>
char *newParentPath = new_pathdup;//pathdup are separated by pathdup, so it take <parent path> only
//put new path info in rename struct
rename_info.newName = lastSlash+1; //\0<direcotry name>, get from <direcotry name>
rename_info.newFileNode = fischl_load_entry(root_node, new_path);
rename_info.newParentNode = strlen(newParentPath)? fischl_load_entry(root_node, newParentPath): root_node->self_info;
//configure with flag
if (flags & RENAME_NOREPLACE) {
// Check if newpath exists and return error if it does
if(rename_info.newFileNode != NULL){
fprintf(stderr,"[%s ,%d] newpath has already existed\n",__func__,__LINE__);
free(new_pathdup);//new path
free(pathdup);//old path
return -1;
}
}
if (flags & RENAME_EXCHANGE) {
// Ensure both oldpath and newpath exist and exchange them atomically
if(rename_info.newFileNode == NULL){
fprintf(stderr,"[%s ,%d] newpath does not exist cannot exchange\n",__func__,__LINE__);
free(new_pathdup);
free(pathdup);
return -1;
}
rename_info.exchangeExist = true;
}
// Normal rename logic if no flags are specified; can overwirte
// Hard Disk rename
u_int64_t parent_inode_number = parent_filenode->inode_number;
u_int64_t target_inode = 0;
// remove its record from parent
INode_Data parent_INode;
parent_INode.inode_num = rename_info.oldParentNode->inode_number;
parent_INode.inode_num = parent_inode_number;
fs->inode_manager->load_inode(&parent_INode);
char rw_buffer[IO_BLOCK_SIZE] = {0};
// relocate the old path file to new path
INode_Data ret;
ret.inode_num = rename_info.oldFileNode->inode_number;
fs->inode_manager->load_inode(&ret);
if(insert_inode_to(rename_info.newParentNode->inode_number, rename_info.newName, &ret)<0){
return -1;
}
bool change_flag = false;
//delete record on old path
for (u_int64_t idx=0; idx<parent_INode.metadata.size/IO_BLOCK_SIZE; idx++) {
fs->read(&parent_INode, rw_buffer, IO_BLOCK_SIZE, idx*IO_BLOCK_SIZE);
DirectoryEntry ent;
for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){
ent.deserialize(rw_buffer+i);
if (strcmp(ent.file_name, filename)==0) {
change_flag = true;//should be change
target_inode = ent.inode_number;
ent.inode_number = 0;
memset(ent.file_name, 0, sizeof(ent.file_name));
ent.serialize(rw_buffer+i);
break;
}
}
if (change_flag) {
if (target_inode) {
fs->write(&parent_INode, rw_buffer, IO_BLOCK_SIZE, idx*IO_BLOCK_SIZE);
change_flag = false;
break;
}
}
//free path
// remove inode itself
if (target_inode) {
INode_Data ret;
ret.inode_num = target_inode;
fs->inode_manager->load_inode(&ret);
fischl_rm_entry(parent_filenode->subdirectory, filename);
printf("FOUND INODE AT %llu %s\n", target_inode, new_name);
char *pathdup2 = strdup(new_name);
char *lastSlash2 = strrchr(pathdup2, '/');
*lastSlash2 = '\0'; // Split the string into parent path and new directory name; <parent path>\0<direcotry name>
char *newDirname2 = lastSlash2+1; //\0<direcotry name>, get from <direcotry name>
char *ParentPath2 = pathdup2;//pathdup are separated by pathdup, so it take <parent path> only
FileNode *parent_filenode2 = strlen(ParentPath)? fischl_load_entry(root_node, ParentPath2): root_node->self_info;
if (parent_filenode2 == NULL) {
fprintf(stderr,"[%s ,%d] ParentPath:{%s} not found\n",__func__,__LINE__, ParentPath2);
free(pathdup2);
return -ENOENT;//parentpath directory does not exist
}
u_int64_t parent_inode_number = parent_filenode->inode_number;
//printf("%s, %llu, %s\n", parent_filenode->name, parent_inode_number, newDirname);
//make new inode
if(insert_inode_to(parent_inode_number, newDirname2, &ret)<0){
return -1;
}
fischl_add_entry(parent_filenode->subdirectory, ret.inode_num, newDirname2, &ret);
free(pathdup);
free(new_pathdup);
// remove node itself and from parent hash
free(pathdup2);
return 0;
} else {
printf("cannot find %s in %s", filename, ParentPath);
free(pathdup);
return -1;
}
}
int FilesOperation::fischl_truncate(const char *path, off_t offset, struct fuse_file_info *fi){

View File

@ -147,7 +147,7 @@ static const struct fuse_operations fischl_oper = {
.unlink = fischl_unlink,
.rmdir = fischl_rmdir,
.symlink = fischl_symlink,
//.rename = fischl_rename,
.rename = fischl_rename,
.link = fischl_link,
.chmod = fischl_chmod,
.chown = fischl_chown,