diff --git a/include/files.h b/include/files.h index 5379139..95206b8 100644 --- a/include/files.h +++ b/include/files.h @@ -27,6 +27,9 @@ class FilesOperation { int fischl_readdir(const char *, void *, fuse_fill_dir_t, off_t, struct fuse_file_info *, enum fuse_readdir_flags); int fischl_releasedir(const char* path, struct fuse_file_info *fi); int fischl_unlink (const char *); + int fischl_rmdir(const char *); + int fischl_chmod(const char *path, mode_t, struct fuse_file_info *fi); + int fischl_chown(const char *path, uid_t uid, gid_t gid, struct fuse_file_info *fi); int fischl_open (const char *, struct fuse_file_info *);//open file int fischl_release (const char *, struct fuse_file_info *);//close file int fischl_write(const char *, const char *, size_t, off_t, struct fuse_file_info *); diff --git a/lib/files.cpp b/lib/files.cpp index f00e457..032955c 100644 --- a/lib/files.cpp +++ b/lib/files.cpp @@ -376,6 +376,99 @@ void FilesOperation::unlink_inode(u_int64_t inode_number) { fs->inode_manager->free_inode(&inode); } +int FilesOperation::fischl_rmdir(const char* path) { + char *pathdup = strdup(path); + char *lastSlash = strrchr(pathdup, '/'); + *lastSlash = '\0'; + char *dirname = lastSlash+1; + char *ParentPath = pathdup; + if (!strcmp(dirname,".")||!strcmp(dirname,"..")) { + printf("refusing 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); + free(pathdup); + return -1; + } + 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 = parent_inode_number; + fs->inode_manager->load_inode(&parent_INode); + char rw_buffer[IO_BLOCK_SIZE] = {0}; + 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, dirname)==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; + } + } + + // remove inode itself + if (target_inode) { + unlink_inode(target_inode); + // remove node itself and from parent hash + fischl_rm_entry(parent_filenode->subdirectory, dirname); + free(pathdup); + return 0; + } else { + printf("cannot find %s in %s", dirname, ParentPath); + free(pathdup); + return -1; + } +} + +int FilesOperation::fischl_chmod(const char *path, mode_t mode, struct fuse_file_info *fi) { + (void) fi; + int res = 0; + u_int64_t fh = namei(path); + + if (fh == -1){ + return -ENOENT; + } + + INode_Data inode; + inode.inode_num = fh; + fs->inode_manager->load_inode(&inode); + inode.metadata.permissions = mode; + fs->inode_manager->save_inode(&inode); + return 0; +} + +int FilesOperation::fischl_chown(const char *path, uid_t uid, gid_t gid, struct fuse_file_info *fi) { + (void) fi; + int res = 0; + u_int64_t fh = namei(path); + + if (fh == -1){ + return -ENOENT; + } + + INode_Data inode; + inode.inode_num = fh; + fs->inode_manager->load_inode(&inode); + inode.metadata.uid = uid; + inode.metadata.gid = gid; + fs->inode_manager->save_inode(&inode); + return 0; +} + + int FilesOperation::fischl_unlink(const char* path) { char *pathdup = strdup(path); char *lastSlash = strrchr(pathdup, '/'); @@ -482,6 +575,7 @@ int FilesOperation::fischl_write(const char *path, const char *buf, size_t size, char buffer[size]; strcpy(buffer, buf); + printf("received offset %d\n", 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_offset = offset % IO_BLOCK_SIZE; // Offset within the first block @@ -496,6 +590,7 @@ int FilesOperation::fischl_write(const char *path, const char *buf, size_t size, block_offset = 0; // Only the first block might have a non-zero offset }*/ fs->inode_manager->save_inode(&inode); + printf("received offset %llu\n", inode.metadata.size); return bytes_write; // Return the actual number of bytes read } diff --git a/lib/fischl.cpp b/lib/fischl.cpp index 4ad6573..40dc8bc 100644 --- a/lib/fischl.cpp +++ b/lib/fischl.cpp @@ -84,7 +84,7 @@ static int fischl_unlink(const char* path) { } static int fischl_rmdir(const char* path) { - return -1; + return options.fsop->fischl_rmdir(path); } static int fischl_symlink(const char* to, const char* from) { @@ -99,12 +99,12 @@ static int fischl_link(const char* from, const char* to) { return -1; } -static int fischl_chmod(const char *path, mode_t, struct fuse_file_info *fi) { - return -1; +static int fischl_chmod(const char *path, mode_t mode, struct fuse_file_info *fi) { + return options.fsop->fischl_chmod(path, mode, fi); } -static int fischl_chown(const char *path, uid_t, gid_t, struct fuse_file_info *fi) { - return -1; +static int fischl_chown(const char *path, uid_t uid, gid_t gid, struct fuse_file_info *fi) { + return options.fsop->fischl_chown(path, uid, gid, fi); } static int fischl_truncate(const char *path, off_t, struct fuse_file_info *fi) { @@ -136,7 +136,7 @@ static int fischl_release(const char* path, struct fuse_file_info *fi) { } static int fischl_releasedir(const char* path, struct fuse_file_info *fi) { - return -1; + return options.fsop->fischl_releasedir(path, fi); } static int fischl_bmap(const char* path, size_t blocksize, uint64_t* blockno) { @@ -160,12 +160,12 @@ static const struct fuse_operations fischl_oper = { .mknod = fischl_mknod, .mkdir = fischl_mkdir, .unlink = fischl_unlink, - //.rmdir = fischl_rmdir, + .rmdir = fischl_rmdir, //.symlink = fischl_symlink, //.rename = fischl_rename, //.link = fischl_link, - //.chmod = fischl_chmod, - //.chown = fischl_chown, + .chmod = fischl_chmod, + .chown = fischl_chown, //.truncate = fischl_truncate, .open = fischl_open, .read = fischl_read, diff --git a/lib/fs/fs_read_write.cpp b/lib/fs/fs_read_write.cpp index 1aabf8a..1dda70a 100644 --- a/lib/fs/fs_read_write.cpp +++ b/lib/fs/fs_read_write.cpp @@ -61,13 +61,16 @@ int Fs::sweep_datablocks(u_int64_t *block_num, int indirect_num, int err; int result = -1; + printf("SURVIVED 1\n"); if (allocate && (*block_num) == 0) if ((err = datablock_manager->new_datablock(block_num)) < 0) return err; - + + printf("SURVIVED 2 %d\n", indirect_num); if (indirect_num == 0) return op->operation(*block_num); + printf("SURVIVED 3\n"); if ((*block_num) == 0) { memset(buf, 0, sizeof(buf)); } else { @@ -101,11 +104,11 @@ int Fs::sweep_datablocks(u_int64_t *block_num, int indirect_num, if (result == 0) break; } - + printf("SURVIVED 4 %llu %d %llu\n", *block_num, result, this_layer_start_index); if (modified) if ((err = disk->write_block(*block_num, buf)) < 0) return err; - + printf("SURVIVED 5 %d\n", result); return result; } @@ -201,12 +204,16 @@ ssize_t Fs::write(INode_Data *inode_data, char buf[], size_t count, op.bytes_completed = 0; op.disk = disk; + printf("trying to write %d %llu %llu\n", op.count, offset, start_block_index); + if ((err = sweep_inode_datablocks(inode_data, start_block_index, true, &op)) < 0) return err; - inode_data->metadata.size = - std::max(offset + op.bytes_completed, inode_data->metadata.size); + inode_data->metadata.size = offset + op.bytes_completed; + //std::max(offset + op.bytes_completed, inode_data->metadata.size); + + printf("written %d\n", op.bytes_completed); return op.bytes_completed; } \ No newline at end of file diff --git a/lib/rawdisk.cpp b/lib/rawdisk.cpp index c0ed0ab..fb1e5f2 100644 --- a/lib/rawdisk.cpp +++ b/lib/rawdisk.cpp @@ -123,6 +123,8 @@ int FakeRawDisk::read_block(u_int64_t block_number, char *buffer) { int FakeRawDisk::write_block(u_int64_t block_number, char *buffer) { u_int64_t offset = block_number * IO_BLOCK_SIZE; + printf("fake disk write: %llu %llu %llu\n", block_number, offset, diskSize); + if (offset + IO_BLOCK_SIZE > diskSize) { perror("Error writing past fake disk size"); return -1;