From 6fe01302b54c8f291441456c46a25107fc70ea60 Mon Sep 17 00:00:00 2001 From: FactorialN <8838579+FactorialN@users.noreply.github.com> Date: Sat, 2 Dec 2023 02:32:19 -0800 Subject: [PATCH] implemented hard link --- include/files.h | 1 + lib/files.cpp | 49 ++++++++++++++++++++++++++++++++++++---- lib/fischl.cpp | 6 ++--- lib/fs/fs_data_types.cpp | 2 +- lib/fs/fs_read_write.cpp | 1 - 5 files changed, 50 insertions(+), 9 deletions(-) diff --git a/include/files.h b/include/files.h index 5eeb57a..e2a27eb 100644 --- a/include/files.h +++ b/include/files.h @@ -29,6 +29,7 @@ class FilesOperation { int fischl_releasedir(const char* path, struct fuse_file_info *fi); int fischl_unlink (const char *); int fischl_rmdir(const char *); + int fischl_link(const char* from, const char* to); int fischl_rename(const char *path, const char *, unsigned int flags); int fischl_truncate(const char *path, off_t, struct fuse_file_info *fi); int fischl_chmod(const char *path, mode_t, struct fuse_file_info *fi); diff --git a/lib/files.cpp b/lib/files.cpp index beb47c1..3f181cc 100644 --- a/lib/files.cpp +++ b/lib/files.cpp @@ -297,20 +297,22 @@ int FilesOperation::fischl_getattr(const char *path, struct stat *stbuf, struct inode.inode_num = fh; fs->inode_manager->load_inode(&inode); - memset(stbuf, 0, sizeof(struct stat)); + //memset(stbuf, 0, sizeof(struct stat)); if ((inode.metadata.permissions & S_IFMT) == S_IFDIR) { stbuf->st_mode = S_IFDIR | 0755; - stbuf->st_nlink = inode.metadata.reference_count; + stbuf->st_nlink = 2;//inode.metadata.reference_count; stbuf->st_uid = inode.metadata.uid; stbuf->st_gid = inode.metadata.gid; + stbuf->st_ino = inode.inode_num; } else { stbuf->st_mode = S_IFREG | 0444; stbuf->st_nlink = inode.metadata.reference_count; stbuf->st_uid = inode.metadata.uid; stbuf->st_gid = inode.metadata.gid; stbuf->st_size = inode.metadata.size; + stbuf->st_ino = inode.inode_num; } - perror(std::to_string(inode.metadata.size).c_str()); + perror(std::to_string(inode.inode_num).c_str()); return res; } @@ -353,6 +355,11 @@ void FilesOperation::unlink_inode(u_int64_t inode_number) { INode_Data inode; inode.inode_num = inode_number; fs->inode_manager->load_inode(&inode); + if (inode.metadata.reference_count > 1 && (inode.metadata.permissions & S_IFMT) != S_IFDIR){ + inode.metadata.reference_count -= 1; + fs->inode_manager->save_inode(&inode); + return; + } if ((inode.metadata.permissions & S_IFMT) == S_IFDIR) { char buffer[IO_BLOCK_SIZE] = {0}; for(u_int64_t idx=0; idxwrite(&inode, buffer, size, offset); /*size_t block_index = offset / IO_BLOCK_SIZE; // Starting block index size_t block_offset = offset % IO_BLOCK_SIZE; // Offset within the first block @@ -667,6 +673,41 @@ int FilesOperation::insert_inode_to(u_int64_t parent_inode_number, const char* n return 0; } +int FilesOperation::fischl_link(const char* from, const char* to){ + + FileNode *get_file; + if((get_file = fischl_find_entry(root_node, from)) == NULL) + return -ENOENT; + INode_Data ret; + ret.inode_num = get_file->inode_number; + fs->inode_manager->load_inode(&ret); + + //check path + char *pathdup = strdup(to); + char *lastSlash = strrchr(pathdup, '/'); + *lastSlash = '\0'; // Split the string into parent path and new directory name; \0 + char *newFilename = lastSlash+1; //\0, get from + char *ParentPath = pathdup;//pathdup are separated by pathdup, so it take only + // fprintf(stderr,"[%s ,%d] ParentPath:%s, strlen=%d\n",__func__,__LINE__, ParentPath, strlen(ParentPath)); + FileNode *parent_filenode = strlen(ParentPath)? fischl_find_entry(root_node, ParentPath): root_node->self_info; + if (parent_filenode == NULL) { + fprintf(stderr,"[%s ,%d] ParentPath:{%s} not found\n",__func__,__LINE__, ParentPath); + free(pathdup); + return -1; + } + + u_int64_t parent_inode_number = parent_filenode->inode_number; + if(insert_inode_to(parent_inode_number, newFilename, &ret)<0){ + return -1; + } + + ret.metadata.reference_count += 1; + fs->inode_manager->save_inode(&ret); + fischl_add_entry(parent_filenode->subdirectory, ret.inode_num, newFilename, &ret); + free(pathdup); + return 0; +} + // TODO: rename dir and rename fail int FilesOperation::fischl_rename(const char *path, const char *new_name, unsigned int flags){ diff --git a/lib/fischl.cpp b/lib/fischl.cpp index 433faa7..31ee820 100644 --- a/lib/fischl.cpp +++ b/lib/fischl.cpp @@ -46,7 +46,7 @@ void fischl_destroy(void* private_data) { } static int fischl_getattr(const char *path, struct stat *stbuf, struct fuse_file_info *fi) { - return options.fsop->fischl_getattr(path, stbuf, fi); + return options.fsop->fischl_getattr(path, stbuf, fi); } static int fischl_access(const char* path, int mask) { @@ -94,7 +94,7 @@ static int fischl_rename(const char *path, const char *new_name, unsigned int fl } static int fischl_link(const char* from, const char* to) { - return -1; + return options.fsop->fischl_link(from, to); } static int fischl_chmod(const char *path, mode_t mode, struct fuse_file_info *fi) { @@ -149,7 +149,7 @@ static const struct fuse_operations fischl_oper = { .rmdir = fischl_rmdir, //.symlink = fischl_symlink, .rename = fischl_rename, - //.link = fischl_link, + .link = fischl_link, .chmod = fischl_chmod, .chown = fischl_chown, .truncate = fischl_truncate, diff --git a/lib/fs/fs_data_types.cpp b/lib/fs/fs_data_types.cpp index c253b02..425f910 100644 --- a/lib/fs/fs_data_types.cpp +++ b/lib/fs/fs_data_types.cpp @@ -54,7 +54,7 @@ INode_Data::INode_Data(u_int64_t inode_num) : inode_num(inode_num) { metadata.gid = -1; metadata.permissions = -1; metadata.size = 0; - metadata.reference_count = 0; + metadata.reference_count = 1; single_indirect_block = double_indirect_block = triple_indirect_block = 0; diff --git a/lib/fs/fs_read_write.cpp b/lib/fs/fs_read_write.cpp index 579fd08..e7f1d6a 100644 --- a/lib/fs/fs_read_write.cpp +++ b/lib/fs/fs_read_write.cpp @@ -15,7 +15,6 @@ int Fs::sweep_inode_datablocks(INode_Data *inode_data, DatablockOperation *op) { int result; - printf("NOW AT %llu %llu %llu %llu %llu\n", NUMBER_OF_DIRECT_BLOCKS, INDIRECT_BLOCKS, INDIRECT_BLOCKS * INDIRECT_BLOCKS, inode_data->single_indirect_block, inode_data->double_indirect_block); u_int64_t start_index = start_block_index; for (size_t i = start_index; i < NUMBER_OF_DIRECT_BLOCKS; ++i) {