diff --git a/include/direntry.h b/include/direntry.h index 20b270e..610fdbb 100644 --- a/include/direntry.h +++ b/include/direntry.h @@ -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); diff --git a/lib/direntry.cpp b/lib/direntry.cpp index 4eaa62e..2f3d2b4 100644 --- a/lib/direntry.cpp +++ b/lib/direntry.cpp @@ -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; } diff --git a/lib/files.cpp b/lib/files.cpp index f7b7178..3e8652e 100644 --- a/lib/files.cpp +++ b/lib/files.cpp @@ -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; \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_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; 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) { - 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 - free(pathdup); - free(new_pathdup); - return 0; + + // 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; \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_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); + // 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){ diff --git a/lib/fischl.cpp b/lib/fischl.cpp index 6ea0798..162c76d 100644 --- a/lib/fischl.cpp +++ b/lib/fischl.cpp @@ -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,