implemented hard link

This commit is contained in:
FactorialN 2023-12-02 02:32:19 -08:00
parent 998e8a20cc
commit 6fe01302b5
5 changed files with 50 additions and 9 deletions

View File

@ -29,6 +29,7 @@ class FilesOperation {
int fischl_releasedir(const char* path, struct fuse_file_info *fi); int fischl_releasedir(const char* path, struct fuse_file_info *fi);
int fischl_unlink (const char *); int fischl_unlink (const char *);
int fischl_rmdir(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_rename(const char *path, const char *, unsigned int flags);
int fischl_truncate(const char *path, off_t, struct fuse_file_info *fi); 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); int fischl_chmod(const char *path, mode_t, struct fuse_file_info *fi);

View File

@ -297,20 +297,22 @@ int FilesOperation::fischl_getattr(const char *path, struct stat *stbuf, struct
inode.inode_num = fh; inode.inode_num = fh;
fs->inode_manager->load_inode(&inode); 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) { if ((inode.metadata.permissions & S_IFMT) == S_IFDIR) {
stbuf->st_mode = S_IFDIR | 0755; 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_uid = inode.metadata.uid;
stbuf->st_gid = inode.metadata.gid; stbuf->st_gid = inode.metadata.gid;
stbuf->st_ino = inode.inode_num;
} else { } else {
stbuf->st_mode = S_IFREG | 0444; stbuf->st_mode = S_IFREG | 0444;
stbuf->st_nlink = inode.metadata.reference_count; stbuf->st_nlink = inode.metadata.reference_count;
stbuf->st_uid = inode.metadata.uid; stbuf->st_uid = inode.metadata.uid;
stbuf->st_gid = inode.metadata.gid; stbuf->st_gid = inode.metadata.gid;
stbuf->st_size = inode.metadata.size; 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; return res;
} }
@ -353,6 +355,11 @@ void FilesOperation::unlink_inode(u_int64_t inode_number) {
INode_Data inode; INode_Data inode;
inode.inode_num = inode_number; inode.inode_num = inode_number;
fs->inode_manager->load_inode(&inode); 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) { 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/IO_BLOCK_SIZE; idx++) { for(u_int64_t idx=0; idx<inode.metadata.size/IO_BLOCK_SIZE; idx++) {
@ -581,7 +588,6 @@ int FilesOperation::fischl_write(const char *path, const char *buf, size_t size,
// Allocate memory for the new buffer // Allocate memory for the new buffer
char* buffer = (char*)malloc(size); char* buffer = (char*)malloc(size);
memcpy(buffer, buf, size); memcpy(buffer, buf, size);
printf("SOME DATA %d %d\n", (int)buffer[0], (int)buffer[1]);
size_t bytes_write = fs->write(&inode, buffer, size, offset); size_t bytes_write = fs->write(&inode, buffer, size, offset);
/*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
@ -667,6 +673,41 @@ int FilesOperation::insert_inode_to(u_int64_t parent_inode_number, const char* n
return 0; 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; <parent path>\0<direcotry name>
char *newFilename = lastSlash+1; //\0<direcotry name>, get from <direcotry name>
char *ParentPath = pathdup;//pathdup are separated by pathdup, so it take <parent path> 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 // TODO: rename dir and rename fail
int FilesOperation::fischl_rename(const char *path, const char *new_name, unsigned int flags){ int FilesOperation::fischl_rename(const char *path, const char *new_name, unsigned int flags){

View File

@ -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) { 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) { 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) { 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) { 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, .rmdir = fischl_rmdir,
//.symlink = fischl_symlink, //.symlink = fischl_symlink,
.rename = fischl_rename, .rename = fischl_rename,
//.link = fischl_link, .link = fischl_link,
.chmod = fischl_chmod, .chmod = fischl_chmod,
.chown = fischl_chown, .chown = fischl_chown,
.truncate = fischl_truncate, .truncate = fischl_truncate,

View File

@ -54,7 +54,7 @@ INode_Data::INode_Data(u_int64_t inode_num) : inode_num(inode_num) {
metadata.gid = -1; metadata.gid = -1;
metadata.permissions = -1; metadata.permissions = -1;
metadata.size = 0; metadata.size = 0;
metadata.reference_count = 0; metadata.reference_count = 1;
single_indirect_block = double_indirect_block = triple_indirect_block = 0; single_indirect_block = double_indirect_block = triple_indirect_block = 0;

View File

@ -15,7 +15,6 @@ int Fs::sweep_inode_datablocks(INode_Data *inode_data,
DatablockOperation *op) { DatablockOperation *op) {
int result; 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; u_int64_t start_index = start_block_index;
for (size_t i = start_index; i < NUMBER_OF_DIRECT_BLOCKS; ++i) { for (size_t i = start_index; i < NUMBER_OF_DIRECT_BLOCKS; ++i) {