From afd3ba7f3269aa552df9ea534624af15d615aaba Mon Sep 17 00:00:00 2001 From: Victor Date: Sat, 2 Dec 2023 13:07:20 -0800 Subject: [PATCH] create renameInfo structure to find file via cache and configure function with flag(still under construct) --- include/direntry.h | 9 +++ lib/files.cpp | 146 ++++++++++++++++++++++----------------------- 2 files changed, 79 insertions(+), 76 deletions(-) diff --git a/include/direntry.h b/include/direntry.h index 7177f0e..e349ed9 100644 --- a/include/direntry.h +++ b/include/direntry.h @@ -19,6 +19,15 @@ 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. + FileNode *newParentNode; // The target parent directory where the file node will be moved. + 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; + /*for root*/ 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 */ diff --git a/lib/files.cpp b/lib/files.cpp index f1e6d9a..77705e5 100644 --- a/lib/files.cpp +++ b/lib/files.cpp @@ -775,109 +775,103 @@ int FilesOperation::fischl_link(const char* from, const char* to){ // TODO: rename dir and rename fail -int FilesOperation::fischl_rename(const char *path, const char *new_name, unsigned int flags){ - char *pathdup = strdup(path); +int FilesOperation::fischl_rename(const char *old_path, const char *new_path, unsigned int flags){ + //find old path + char *pathdup = strdup(old_path); char *lastSlash = strrchr(pathdup, '/'); *lastSlash = '\0'; char *filename = lastSlash+1; - char *ParentPath = pathdup; + char *oldParentPath = pathdup; if (!strcmp(filename,".")||!strcmp(filename,"..")) { - printf("refusing to remove . or ..\n"); + printf("refuse to remove . or ..\n"); return -1; } - FileNode *parent_filenode = fischl_find_entry(root_node, ParentPath); - if (parent_filenode == NULL) { - printf("parent %s not found by fischl_find_entry\n", ParentPath); + //put old path info in rename struct + RenameInfo rename_info; + rename_info.exchangeExist = false; + rename_info.oldParentNode = fischl_find_entry(root_node, oldParentPath); + rename_info.oldFileNode = fischl_find_entry(rename_info.oldParentNode->subdirectory, filename); + + if (rename_info.oldFileNode == NULL) { + printf("path %s not found by fischl_find_entry\n", old_path); free(pathdup); return -1; } - u_int64_t parent_inode_number = parent_filenode->inode_number; - u_int64_t target_inode = 0; + //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; \0 + char *newParentPath = new_pathdup;//pathdup are separated by pathdup, so it take only + //put new path info in rename struct + rename_info.newName = lastSlash+1; //\0, get from + rename_info.newFileNode = fischl_find_entry(root_node, new_path); + rename_info.newParentNode = strlen(newParentPath)? fischl_find_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 + // remove its record from parent INode_Data parent_INode; - parent_INode.inode_num = parent_inode_number; + parent_INode.inode_num = rename_info.oldParentNode->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; idxread(&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) { - target_inode = ent.inode_number; + change_flag = true;//should be change + ent.inode_number = 0; + memset(ent.file_name, 0, sizeof(ent.file_name)); + ent.serialize(rw_buffer+i); break; } } - if (target_inode){ + if (change_flag) { + fs->write(&parent_INode, rw_buffer, IO_BLOCK_SIZE, idx*IO_BLOCK_SIZE); + change_flag = false; break; } } - // remove inode itself - if (target_inode) { - INode_Data ret; - ret.inode_num = target_inode; - fs->inode_manager->load_inode(&ret); - - if (flags == RENAME_EXCHANGE){ - printf("RENAME_EXCHANGE "); - } - else if (flags == RENAME_NOREPLACE){ - printf("RENAME_NOREPLACE "); - } - else printf("ELSE "); - - 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; \0 - char *newDirname2 = lastSlash2+1; //\0, get from - char *ParentPath2 = pathdup2;//pathdup are separated by pathdup, so it take only - - FileNode *parent_filenode2 = strlen(ParentPath)? fischl_find_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_number2 = parent_filenode2->inode_number; - //printf("%s, %llu, %s\n", parent_filenode->name, parent_inode_number, newDirname); - //make new inode - if(insert_inode_to(parent_inode_number2, newDirname2, &ret)<0){ - return -1; - } - - for (u_int64_t idx=0; idxread(&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) { - 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 (target_inode) { - fs->write(&parent_INode, rw_buffer, IO_BLOCK_SIZE, idx*IO_BLOCK_SIZE); - break; - } - } - - fischl_rm_entry(parent_filenode->subdirectory, filename); - fischl_add_entry(parent_filenode2->subdirectory, ret.inode_num, newDirname2, &ret); - free(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; - } + //free path + free(pathdup); + free(new_pathdup); + return 0; } int FilesOperation::fischl_truncate(const char *path, off_t offset, struct fuse_file_info *fi){