Compare commits

..

No commits in common. "main" and "guangzheliu/layer3dev" have entirely different histories.

8 changed files with 791 additions and 946 deletions

View File

@ -18,7 +18,7 @@ public:
ssize_t read(INode_Data *inode_data, char buf[], size_t count, size_t offset); ssize_t read(INode_Data *inode_data, char buf[], size_t count, size_t offset);
ssize_t write(INode_Data *inode_data, const char buf[], size_t count, ssize_t write(INode_Data *inode_data, const char buf[], size_t count,
size_t offset); size_t offset);
int truncate(INode_Data *inode_data, off_t length); int truncate(INode_Data *inode_data, size_t length);
ssize_t lseek_next_data(INode_Data *inode_data, size_t offset); ssize_t lseek_next_data(INode_Data *inode_data, size_t offset);
ssize_t lseek_next_hole(INode_Data *inode_data, size_t offset); ssize_t lseek_next_hole(INode_Data *inode_data, size_t offset);

View File

@ -41,10 +41,6 @@ public:
#define NUMBER_OF_DIRECT_BLOCKS \ #define NUMBER_OF_DIRECT_BLOCKS \
(((INODE_SIZE - NUMBER_OF_METADATA_BYTES) / sizeof(u_int64_t)) - 3) (((INODE_SIZE - NUMBER_OF_METADATA_BYTES) / sizeof(u_int64_t)) - 3)
#define FILE_SIZE_MAX \
(IO_BLOCK_SIZE * (NUMBER_OF_DIRECT_BLOCKS + INDIRECT_BLOCKS + \
(INDIRECT_BLOCKS * INDIRECT_BLOCKS) + \
(INDIRECT_BLOCKS * INDIRECT_BLOCKS * INDIRECT_BLOCKS)))
u_int64_t single_indirect_block, double_indirect_block, triple_indirect_block; u_int64_t single_indirect_block, double_indirect_block, triple_indirect_block;
u_int64_t direct_blocks[NUMBER_OF_DIRECT_BLOCKS]; u_int64_t direct_blocks[NUMBER_OF_DIRECT_BLOCKS];

View File

@ -2,7 +2,6 @@
#define FS_CONSTANTS_HPP #define FS_CONSTANTS_HPP
#include <algorithm> #include <algorithm>
#include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <inttypes.h> #include <inttypes.h>
#include <linux/fs.h> #include <linux/fs.h>
@ -12,11 +11,10 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <unistd.h> #include <unistd.h>
#define IO_BLOCK_SIZE 4096 #define IO_BLOCK_SIZE 4096
#define INDIRECT_BLOCKS 512 #define INDIRECT_BLOCKS 512
#define NUM_INODE_BLOCKS 262143 #define NUM_INODE_BLOCKS 1023
#define INODE_SIZE 512 #define INODE_SIZE 512

View File

@ -55,7 +55,8 @@ void FilesOperation::initialize(bool load) {
root_node = fischl_init_entry(1, "/", root_inode); root_node = fischl_init_entry(1, "/", root_inode);
assert(root_node->self_info!=NULL); assert(root_node->self_info!=NULL);
fs->load_superblock(); fs->load_superblock();
} else { }
else{
initialize_rootinode(); initialize_rootinode();
} }
} }
@ -116,9 +117,7 @@ INode_Data *FilesOperation::create_new_inode(u_int64_t parent_inode_number,
bool allocated = false; bool allocated = false;
INode_Data *new_inode = new INode_Data(); INode_Data *new_inode = new INode_Data();
fs->inode_manager->new_inode(getuid(), getgid(), mode, new_inode); fs->inode_manager->new_inode(getuid(), getgid(), mode, new_inode);
printf("NEW INODE %llu %llu %llu %o\n", new_inode->inode_num, //printf("%llu\n",new_inode->inode_num);
new_inode->metadata.uid, new_inode->metadata.gid,
(mode_t)new_inode->metadata.permissions);
if ((mode & S_IFMT) == S_IFDIR) { if ((mode & S_IFMT) == S_IFDIR) {
create_dot_dotdot(new_inode, parent_inode_number); create_dot_dotdot(new_inode, parent_inode_number);
fs->inode_manager->save_inode(new_inode); fs->inode_manager->save_inode(new_inode);
@ -213,17 +212,14 @@ u_int64_t FilesOperation::disk_namei(const char *path) {
u_int64_t FilesOperation::namei(const char* path) { u_int64_t FilesOperation::namei(const char* path) {
FileNode* filenode = fischl_load_entry(root_node, path); FileNode* filenode = fischl_load_entry(root_node, path);
if (filenode) if (filenode) return filenode->inode_number;
return filenode->inode_number; else return -1;
else
return -1;
} }
bool FilesOperation::permission_check(int mask, INode_Data *inode) { bool FilesOperation::permission_check(int mask, INode_Data *inode) {
mode_t per = (mode_t)inode->metadata.permissions; mode_t per = (mode_t)inode->metadata.permissions;
uid_t uid = (uid_t)inode->metadata.uid; uid_t uid = (uid_t)inode->metadata.uid;
gid_t gid = (gid_t)inode->metadata.gid; gid_t gid = (gid_t)inode->metadata.gid;
if (getuid() == 0) return true;
//printf("PERMISSION CHECK %d %llu %llu %o\n", mask, uid, gid, per); //printf("PERMISSION CHECK %d %llu %llu %o\n", mask, uid, gid, per);
if(getuid() == uid){ if(getuid() == uid){
if ((mask & R_OK) && !(per & S_IRUSR)) { if ((mask & R_OK) && !(per & S_IRUSR)) {
@ -238,7 +234,8 @@ bool FilesOperation::permission_check(int mask, INode_Data *inode) {
return false; // Permission denied for executing return false; // Permission denied for executing
} }
return true; return true;
} else if (getgid() == gid) { }
else if(getgid() == gid){
if ((mask & R_OK) && !(per & S_IRGRP)) { if ((mask & R_OK) && !(per & S_IRGRP)) {
return false; // Permission denied for reading return false; // Permission denied for reading
} }
@ -251,7 +248,8 @@ bool FilesOperation::permission_check(int mask, INode_Data *inode) {
return false; // Permission denied for executing return false; // Permission denied for executing
} }
return true; return true;
} else { }
else{
if ((mask & R_OK) && !(per & S_IROTH)) { if ((mask & R_OK) && !(per & S_IROTH)) {
return false; // Permission denied for reading return false; // Permission denied for reading
} }
@ -267,8 +265,7 @@ bool FilesOperation::permission_check(int mask, INode_Data *inode) {
} }
} }
bool FilesOperation::permission_check_by_inode_num(int mask, bool FilesOperation::permission_check_by_inode_num(int mask, u_int64_t inode_num) {
u_int64_t inode_num) {
INode_Data inode; INode_Data inode;
inode.inode_num = inode_num; inode.inode_num = inode_num;
@ -305,12 +302,9 @@ int FilesOperation::fischl_mkdir(const char *path, mode_t mode) {
char *ParentPath = pathdup; // pathdup are separated by pathdup, so it take char *ParentPath = pathdup; // pathdup are separated by pathdup, so it take
// <parent path> only // <parent path> only
FileNode *parent_filenode = strlen(ParentPath) FileNode *parent_filenode = strlen(ParentPath)? fischl_load_entry(root_node, ParentPath): root_node->self_info;
? fischl_load_entry(root_node, ParentPath)
: root_node->self_info;
if (parent_filenode == NULL) { if (parent_filenode == NULL) {
fprintf(stderr, "[%s ,%d] ParentPath:{%s} not found\n", __func__, __LINE__, fprintf(stderr,"[%s ,%d] ParentPath:{%s} not found\n",__func__,__LINE__, ParentPath);
ParentPath);
free(pathdup); free(pathdup);
return -ENOENT;//parentpath directory does not exist return -ENOENT;//parentpath directory does not exist
} }
@ -319,15 +313,11 @@ int FilesOperation::fischl_mkdir(const char *path, mode_t mode) {
return -EACCES; return -EACCES;
} }
// printf("%s, %llu, %s\n", parent_filenode->name, parent_inode_number, //printf("%s, %llu, %s\n", parent_filenode->name, parent_inode_number, newDirname);
// newDirname); make new inode //make new inode
INode_Data *ret = INode_Data* ret = create_new_inode(parent_inode_number, newDirname, mode|S_IFDIR);//specify S_IFDIR as directory
create_new_inode(parent_inode_number, newDirname, if (ret == NULL) return -1;//ENOSPC but create_new_inode handle ENAMETOOLONG EEXIST
mode | S_IFDIR); // specify S_IFDIR as directory fischl_add_entry(parent_filenode->subdirectory, ret->inode_num, newDirname, ret);
if (ret == NULL)
return -1; // ENOSPC but create_new_inode handle ENAMETOOLONG EEXIST
fischl_add_entry(parent_filenode->subdirectory, ret->inode_num, newDirname,
ret);
free(pathdup); free(pathdup);
return 0;//SUCCESS return 0;//SUCCESS
} }
@ -338,20 +328,13 @@ int FilesOperation::fischl_mknod(const char *path, mode_t mode, dev_t dev) {
//check path //check path
char *pathdup = strdup(path); char *pathdup = strdup(path);
char *lastSlash = strrchr(pathdup, '/'); char *lastSlash = strrchr(pathdup, '/');
*lastSlash = '\0'; // Split the string into parent path and new directory *lastSlash = '\0'; // Split the string into parent path and new directory name; <parent path>\0<direcotry name>
// name; <parent path>\0<direcotry name> char *newFilename = lastSlash+1; //\0<direcotry name>, get from <direcotry name>
char *newFilename = char *ParentPath = pathdup;//pathdup are separated by pathdup, so it take <parent path> only
lastSlash + 1; //\0<direcotry name>, get from <direcotry name> // fprintf(stderr,"[%s ,%d] ParentPath:%s, strlen=%d\n",__func__,__LINE__, ParentPath, strlen(ParentPath));
char *ParentPath = pathdup; // pathdup are separated by pathdup, so it take FileNode *parent_filenode = strlen(ParentPath)? fischl_load_entry(root_node, ParentPath): root_node->self_info;
// <parent path> only
// fprintf(stderr,"[%s ,%d] ParentPath:%s, strlen=%d\n",__func__,__LINE__,
// ParentPath, strlen(ParentPath));
FileNode *parent_filenode = strlen(ParentPath)
? fischl_load_entry(root_node, ParentPath)
: root_node->self_info;
if (parent_filenode == NULL) { if (parent_filenode == NULL) {
fprintf(stderr, "[%s ,%d] ParentPath:{%s} not found\n", __func__, __LINE__, fprintf(stderr,"[%s ,%d] ParentPath:{%s} not found\n",__func__,__LINE__, ParentPath);
ParentPath);
free(pathdup); free(pathdup);
return -1; return -1;
} }
@ -361,36 +344,26 @@ int FilesOperation::fischl_mknod(const char *path, mode_t mode, dev_t dev) {
} }
//make new inode //make new inode
INode_Data* ret = create_new_inode(parent_inode_number, newFilename, mode); INode_Data* ret = create_new_inode(parent_inode_number, newFilename, mode);
if (ret == NULL) if (ret == NULL) return -1;//ENOSPC but create_new_inode handle ENAMETOOLONG EEXIST
return -1; // ENOSPC but create_new_inode handle ENAMETOOLONG EEXIST
//make new node //make new node
fischl_add_entry(parent_filenode->subdirectory, ret->inode_num, newFilename, fischl_add_entry(parent_filenode->subdirectory, ret->inode_num, newFilename, ret);
ret);
free(pathdup); free(pathdup);
return 0;//SUCESS return 0;//SUCESS
} }
/* /*
regular file regular file
*/ */
int FilesOperation::fischl_create(const char *path, mode_t mode, int FilesOperation::fischl_create(const char* path, mode_t mode, struct fuse_file_info* fi) {
struct fuse_file_info *fi) {
//check path //check path
char *pathdup = strdup(path); char *pathdup = strdup(path);
char *lastSlash = strrchr(pathdup, '/'); char *lastSlash = strrchr(pathdup, '/');
*lastSlash = '\0'; // Split the string into parent path and new directory *lastSlash = '\0'; // Split the string into parent path and new directory name; <parent path>\0<direcotry name>
// name; <parent path>\0<direcotry name> char *newFilename = lastSlash+1; //\0<direcotry name>, get from <direcotry name>
char *newFilename = char *ParentPath = pathdup;//pathdup are separated by pathdup, so it take <parent path> only
lastSlash + 1; //\0<direcotry name>, get from <direcotry name> // fprintf(stderr,"[%s ,%d] ParentPath:%s, strlen=%d\n",__func__,__LINE__, ParentPath, strlen(ParentPath));
char *ParentPath = pathdup; // pathdup are separated by pathdup, so it take FileNode *parent_filenode = strlen(ParentPath)? fischl_load_entry(root_node, ParentPath): root_node->self_info;
// <parent path> only
// fprintf(stderr,"[%s ,%d] ParentPath:%s, strlen=%d\n",__func__,__LINE__,
// ParentPath, strlen(ParentPath));
FileNode *parent_filenode = strlen(ParentPath)
? fischl_load_entry(root_node, ParentPath)
: root_node->self_info;
if (parent_filenode == NULL) { if (parent_filenode == NULL) {
fprintf(stderr, "[%s ,%d] ParentPath:{%s} not found\n", __func__, __LINE__, fprintf(stderr,"[%s ,%d] ParentPath:{%s} not found\n",__func__,__LINE__, ParentPath);
ParentPath);
free(pathdup); free(pathdup);
return -1; return -1;
} }
@ -400,14 +373,11 @@ int FilesOperation::fischl_create(const char *path, mode_t mode,
} }
//make new inode //make new inode
INode_Data* ret = create_new_inode(parent_inode_number, newFilename, mode); INode_Data* ret = create_new_inode(parent_inode_number, newFilename, mode);
if (ret == NULL) if (ret == NULL) return -1;//ENOSPC but create_new_inode handle ENAMETOOLONG EEXIST
return -1; // ENOSPC but create_new_inode handle ENAMETOOLONG EEXIST
//make new node in RAM //make new node in RAM
fischl_add_entry(parent_filenode->subdirectory, ret->inode_num, newFilename, fischl_add_entry(parent_filenode->subdirectory, ret->inode_num, newFilename, ret);
ret);
//directly give inode number rather than create file descriptor table //directly give inode number rather than create file descriptor table
fi->fh = fi->fh = ret->inode_num;//assign file descriptor as inode number to fuse system
ret->inode_num; // assign file descriptor as inode number to fuse system
free(pathdup); free(pathdup);
return 0;//SUCESS return 0;//SUCESS
} }
@ -436,8 +406,7 @@ int FilesOperation::fischl_getattr(const char *path, struct stat *stbuf,
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_atime = (time_t)(inode.metadata.access_time / 1000000000ULL); stbuf->st_atime = (time_t)(inode.metadata.access_time / 1000000000ULL);
stbuf->st_mtime = stbuf->st_mtime = (time_t)(inode.metadata.modification_time / 1000000000ULL);
(time_t)(inode.metadata.modification_time / 1000000000ULL);
stbuf->st_size = IO_BLOCK_SIZE; stbuf->st_size = IO_BLOCK_SIZE;
stbuf->st_ino = inode.inode_num; stbuf->st_ino = inode.inode_num;
} else if(S_ISLNK(inode.metadata.permissions)){ } else if(S_ISLNK(inode.metadata.permissions)){
@ -446,8 +415,7 @@ int FilesOperation::fischl_getattr(const char *path, struct stat *stbuf,
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_atime = (time_t)(inode.metadata.access_time / 1000000000ULL); stbuf->st_atime = (time_t)(inode.metadata.access_time / 1000000000ULL);
stbuf->st_mtime = stbuf->st_mtime = (time_t)(inode.metadata.modification_time / 1000000000ULL);
(time_t)(inode.metadata.modification_time / 1000000000ULL);
stbuf->st_size = inode.metadata.size; stbuf->st_size = inode.metadata.size;
stbuf->st_ino = inode.inode_num; stbuf->st_ino = inode.inode_num;
} else { } else {
@ -455,12 +423,8 @@ int FilesOperation::fischl_getattr(const char *path, struct stat *stbuf,
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;
// printf("GETATTR %llu %llu %llu %o\n", inode.inode_num,
// inode.metadata.uid, inode.metadata.gid,
// (mode_t)inode.metadata.permissions);
stbuf->st_atime = (time_t)(inode.metadata.access_time / 1000000000ULL); stbuf->st_atime = (time_t)(inode.metadata.access_time / 1000000000ULL);
stbuf->st_mtime = stbuf->st_mtime = (time_t)(inode.metadata.modification_time / 1000000000ULL);
(time_t)(inode.metadata.modification_time / 1000000000ULL);
stbuf->st_size = inode.metadata.size; stbuf->st_size = inode.metadata.size;
stbuf->st_ino = inode.inode_num; stbuf->st_ino = inode.inode_num;
} }
@ -501,8 +465,7 @@ int FilesOperation::fischl_readdir(const char *path, void *buf,
return 0; return 0;
} }
int FilesOperation::fischl_releasedir(const char *path, int FilesOperation::fischl_releasedir(const char *path, struct fuse_file_info *fi){
struct fuse_file_info *fi) {
if(fischl_load_entry(root_node, path) == NULL) if(fischl_load_entry(root_node, path) == NULL)
return -ENOENT; return -ENOENT;
//do with file descriptor that cannot be used //do with file descriptor that cannot be used
@ -514,8 +477,7 @@ 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 && if (inode.metadata.reference_count > 1 && (inode.metadata.permissions & S_IFMT) != S_IFDIR){
(inode.metadata.permissions & S_IFMT) != S_IFDIR) {
inode.metadata.reference_count -= 1; inode.metadata.reference_count -= 1;
fs->inode_manager->save_inode(&inode); fs->inode_manager->save_inode(&inode);
return; return;
@ -538,8 +500,7 @@ void FilesOperation::unlink_inode(u_int64_t inode_number) {
fs->inode_manager->free_inode(&inode); fs->inode_manager->free_inode(&inode);
} }
int FilesOperation::fischl_opendir(const char *path, int FilesOperation::fischl_opendir(const char* path, struct fuse_file_info* fi) {
struct fuse_file_info *fi) {
u_int64_t fh = namei(path); u_int64_t fh = namei(path);
@ -585,8 +546,7 @@ int FilesOperation::fischl_rmdir(const char *path) {
return -EACCES; return -EACCES;
} }
char rw_buffer[IO_BLOCK_SIZE] = {0}; char rw_buffer[IO_BLOCK_SIZE] = {0};
for (u_int64_t idx = 0; idx < parent_INode.metadata.size / IO_BLOCK_SIZE; for (u_int64_t idx=0; idx<parent_INode.metadata.size/IO_BLOCK_SIZE; idx++) {
idx++) {
fs->read(&parent_INode, rw_buffer, IO_BLOCK_SIZE, idx*IO_BLOCK_SIZE); fs->read(&parent_INode, rw_buffer, IO_BLOCK_SIZE, idx*IO_BLOCK_SIZE);
DirectoryEntry ent; DirectoryEntry ent;
for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){ for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){
@ -650,16 +610,13 @@ int FilesOperation::fischl_chown(const char *path, uid_t uid, gid_t gid,
INode_Data inode; INode_Data inode;
inode.inode_num = fh; inode.inode_num = fh;
fs->inode_manager->load_inode(&inode); fs->inode_manager->load_inode(&inode);
if (uid != (uid_t)(-1)) {
inode.metadata.uid = uid; inode.metadata.uid = uid;
}
if (gid != (gid_t)(-1)) {
inode.metadata.gid = gid; inode.metadata.gid = gid;
}
fs->inode_manager->save_inode(&inode); fs->inode_manager->save_inode(&inode);
return 0; return 0;
} }
int FilesOperation::fischl_unlink(const char* path) { int FilesOperation::fischl_unlink(const char* path) {
char *pathdup = strdup(path); char *pathdup = strdup(path);
@ -688,8 +645,7 @@ int FilesOperation::fischl_unlink(const char *path) {
return -EACCES; return -EACCES;
} }
char rw_buffer[IO_BLOCK_SIZE] = {0}; char rw_buffer[IO_BLOCK_SIZE] = {0};
for (u_int64_t idx = 0; idx < parent_INode.metadata.size / IO_BLOCK_SIZE; for (u_int64_t idx=0; idx<parent_INode.metadata.size/IO_BLOCK_SIZE; idx++) {
idx++) {
fs->read(&parent_INode, rw_buffer, IO_BLOCK_SIZE, idx*IO_BLOCK_SIZE); fs->read(&parent_INode, rw_buffer, IO_BLOCK_SIZE, idx*IO_BLOCK_SIZE);
DirectoryEntry ent; DirectoryEntry ent;
for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){ for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){
@ -726,8 +682,8 @@ int FilesOperation::fischl_unlink(const char *path) {
} }
int FilesOperation::fischl_open(const char *path, struct fuse_file_info *fi){ int FilesOperation::fischl_open(const char *path, struct fuse_file_info *fi){
/*Creation (O_CREAT, O_EXCL, O_NOCTTY) flags will be filtered out / handled by /*Creation (O_CREAT, O_EXCL, O_NOCTTY) flags will be filtered out / handled by the kernel.
the kernel. if no files will use create function if no files will use create function
*/ */
FileNode *get_file; FileNode *get_file;
if((get_file = fischl_load_entry(root_node, path)) == NULL) if((get_file = fischl_load_entry(root_node, path)) == NULL)
@ -754,16 +710,15 @@ int FilesOperation::fischl_open(const char *path, struct fuse_file_info *fi) {
} }
} }
// if need to do with flag fi->flags ((fi->flags & O_ACCMODE)). Initial //if need to do with flag fi->flags ((fi->flags & O_ACCMODE)). Initial setting ALL access
// setting ALL access create function will handle file descriptor fi->fh //create function will handle file descriptor fi->fh
fi->fh = get_file->inode_number; fi->fh = get_file->inode_number;
return 0;//SUCESS return 0;//SUCESS
} }
int FilesOperation::fischl_release(const char *path, int FilesOperation::fischl_release(const char *path, struct fuse_file_info *fi){
struct fuse_file_info *fi) { /*Creation (O_CREAT, O_EXCL, O_NOCTTY) flags will be filtered out / handled by the kernel.
/*Creation (O_CREAT, O_EXCL, O_NOCTTY) flags will be filtered out / handled by if no files will use create function
the kernel. if no files will use create function
*/ */
FileNode *get_file; FileNode *get_file;
if((get_file = fischl_load_entry(root_node, path)) == NULL) if((get_file = fischl_load_entry(root_node, path)) == NULL)
@ -773,8 +728,7 @@ int FilesOperation::fischl_release(const char *path,
return 0;//SUCESS return 0;//SUCESS
} }
int FilesOperation::fischl_write(const char *path, const char *buf, size_t size, int FilesOperation::fischl_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi){
off_t offset, struct fuse_file_info *fi) {
/** Write data to an open file /** Write data to an open file
* *
* Write should return exactly the number of bytes requested * Write should return exactly the number of bytes requested
@ -788,17 +742,14 @@ int FilesOperation::fischl_write(const char *path, const char *buf, size_t size,
// FileNode *get_file; // FileNode *get_file;
// if((get_file = fischl_load_entry(root_node, path)) == NULL) // if((get_file = fischl_load_entry(root_node, path)) == NULL)
// return -ENOENT; // return -ENOENT;
// Caution! this based on content in file are multiple of IO_BLOCK_SIZE, not // Caution! this based on content in file are multiple of IO_BLOCK_SIZE, not the exact write size.
// the exact write size. based on current write_datablock API implement, when // based on current write_datablock API implement, when write_datablock pass with actual size not index this function should be fixed
// write_datablock pass with actual size not index this function should be
// fixed
INode_Data inode; INode_Data inode;
// Assuming inode is correctly initialized here based on 'path' // Assuming inode is correctly initialized here based on 'path'
inode.inode_num = fi->fh; inode.inode_num = fi->fh;
fs->inode_manager->load_inode(&inode); fs->inode_manager->load_inode(&inode);
// size_t len = (inode.metadata.size/IO_BLOCK_SIZE) * IO_BLOCK_SIZE; // //size_t len = (inode.metadata.size/IO_BLOCK_SIZE) * IO_BLOCK_SIZE; // Assuming each block is 4096 bytes
// Assuming each block is 4096 bytes
// Determine the length of the buffer // Determine the length of the buffer
// Allocate memory for the new buffer // Allocate memory for the new buffer
char* buffer = (char*)malloc(size); char* buffer = (char*)malloc(size);
@ -808,19 +759,16 @@ int FilesOperation::fischl_write(const char *path, const char *buf, size_t size,
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
while (bytes_write < size) { while (bytes_write < size) {
char block_buffer[IO_BLOCK_SIZE]; // Temporary buffer for each block char block_buffer[IO_BLOCK_SIZE]; // Temporary buffer for each block
size_t copy_size = std::min(size - bytes_write, IO_BLOCK_SIZE - size_t copy_size = std::min(size - bytes_write, IO_BLOCK_SIZE - block_offset);
block_offset); memcpy(block_buffer + block_offset, buf + bytes_write, memcpy(block_buffer + block_offset, buf + bytes_write, copy_size);
copy_size); fs->write(&inode, block_buffer, IO_BLOCK_SIZE, fs->write(&inode, block_buffer, IO_BLOCK_SIZE, block_index*IO_BLOCK_SIZE);
block_index*IO_BLOCK_SIZE); // fprintf(stderr,"[%s ,%d] inode.size %d, block_index %d, block_buffer %s\n",__func__,__LINE__, inode.size, block_index, block_buffer);
// fprintf(stderr,"[%s ,%d] inode.size %d, block_index %d, block_buffer bytes_write += copy_size;
%s\n",__func__,__LINE__, inode.size, block_index, block_buffer); bytes_write block_index++;
+= copy_size; block_index++; block_offset = 0; // Only the first block might block_offset = 0; // Only the first block might have a non-zero offset
have a non-zero offset
}*/ }*/
fs->inode_manager->save_inode(&inode); fs->inode_manager->save_inode(&inode);
free(buffer); free(buffer);
if (bytes_write < 0)
return -errno;
return bytes_write; // Return the actual number of bytes read return bytes_write; // Return the actual number of bytes read
} }
@ -857,20 +805,13 @@ int FilesOperation::fischl_symlink(const char *to, const char *from) {
//printf("SYMLINK %s %s\n", from, to); //printf("SYMLINK %s %s\n", from, to);
char *pathdup = strdup(from); char *pathdup = strdup(from);
char *lastSlash = strrchr(pathdup, '/'); char *lastSlash = strrchr(pathdup, '/');
*lastSlash = '\0'; // Split the string into parent path and new directory *lastSlash = '\0'; // Split the string into parent path and new directory name; <parent path>\0<direcotry name>
// name; <parent path>\0<direcotry name> char *newFilename = lastSlash+1; //\0<direcotry name>, get from <direcotry name>
char *newFilename = char *ParentPath = pathdup;//pathdup are separated by pathdup, so it take <parent path> only
lastSlash + 1; //\0<direcotry name>, get from <direcotry name> // fprintf(stderr,"[%s ,%d] ParentPath:%s, strlen=%d\n",__func__,__LINE__, ParentPath, strlen(ParentPath));
char *ParentPath = pathdup; // pathdup are separated by pathdup, so it take FileNode *parent_filenode = strlen(ParentPath)? fischl_load_entry(root_node, ParentPath): root_node->self_info;
// <parent path> only
// fprintf(stderr,"[%s ,%d] ParentPath:%s, strlen=%d\n",__func__,__LINE__,
// ParentPath, strlen(ParentPath));
FileNode *parent_filenode = strlen(ParentPath)
? fischl_load_entry(root_node, ParentPath)
: root_node->self_info;
if (parent_filenode == NULL) { if (parent_filenode == NULL) {
fprintf(stderr, "[%s ,%d] ParentPath:{%s} not found\n", __func__, __LINE__, fprintf(stderr,"[%s ,%d] ParentPath:{%s} not found\n",__func__,__LINE__, ParentPath);
ParentPath);
free(pathdup); free(pathdup);
return -ENOENT; return -ENOENT;
} }
@ -879,13 +820,10 @@ int FilesOperation::fischl_symlink(const char *to, const char *from) {
return -EACCES; return -EACCES;
} }
//make new inode //make new inode
INode_Data *ret = INode_Data* ret = create_new_inode(parent_inode_number, newFilename, S_IFLNK|0777);
create_new_inode(parent_inode_number, newFilename, S_IFLNK | 0777); if (ret == NULL) return -1;//ENOSPC but create_new_inode handle ENAMETOOLONG EEXIST
if (ret == NULL)
return -1; // ENOSPC but create_new_inode handle ENAMETOOLONG EEXIST
//make new node in RAM //make new node in RAM
fischl_add_entry(parent_filenode->subdirectory, ret->inode_num, newFilename, fischl_add_entry(parent_filenode->subdirectory, ret->inode_num, newFilename, ret);
ret);
size_t size = strlen(to); size_t size = strlen(to);
char* buffer = (char*)malloc(size); char* buffer = (char*)malloc(size);
memcpy(buffer, to, size); memcpy(buffer, to, size);
@ -898,9 +836,7 @@ int FilesOperation::fischl_symlink(const char *to, const char *from) {
return 0;//SUCESS return 0;//SUCESS
} }
int FilesOperation::insert_inode_to(u_int64_t parent_inode_number, int FilesOperation::insert_inode_to(u_int64_t parent_inode_number, const char* name, INode_Data *new_inode, bool check_replace) {
const char *name, INode_Data *new_inode,
bool check_replace) {
// trys to create a file under parent directory // trys to create a file under parent directory
if (strlen(name)>=256) { if (strlen(name)>=256) {
perror("Name too long, cannot create file or directory"); perror("Name too long, cannot create file or directory");
@ -910,8 +846,7 @@ int FilesOperation::insert_inode_to(u_int64_t parent_inode_number,
inode.inode_num = parent_inode_number; inode.inode_num = parent_inode_number;
fs->inode_manager->load_inode(&inode); fs->inode_manager->load_inode(&inode);
if ((inode.metadata.permissions & S_IFMT) != S_IFDIR) { if ((inode.metadata.permissions & S_IFMT) != S_IFDIR) {
fprintf(stderr, "[%s ,%d] please create under directory\n", __func__, fprintf(stderr,"[%s ,%d] please create under directory\n",__func__,__LINE__);
__LINE__);
return -1; return -1;
} }
@ -925,15 +860,13 @@ int FilesOperation::insert_inode_to(u_int64_t parent_inode_number,
if (strcmp(ent.file_name, name)==0 && ent.inode_number != 0) { if (strcmp(ent.file_name, name)==0 && ent.inode_number != 0) {
if(check_replace){ if(check_replace){
if((new_inode->metadata.permissions & S_IFMT) == S_IFDIR){ if((new_inode->metadata.permissions & S_IFMT) == S_IFDIR){
fprintf(stderr, "[%s ,%d] %s/ already exists\n", __func__, __LINE__, fprintf(stderr,"[%s ,%d] %s/ already exists\n",__func__,__LINE__, name);
name);
}else{ }else{
fprintf(stderr, "[%s ,%d] %s already exists\n", __func__, __LINE__, fprintf(stderr,"[%s ,%d] %s already exists\n",__func__,__LINE__, name);
name);
} }
return -1; return -1;
} else { }
// printf("RENAME HAPPENS %s %s\n", ); else{
ent.inode_number = new_inode->inode_num; ent.inode_number = new_inode->inode_num;
ent.serialize(r_buffer+i); ent.serialize(r_buffer+i);
fs->write(&inode, r_buffer, IO_BLOCK_SIZE, idx*IO_BLOCK_SIZE); fs->write(&inode, r_buffer, IO_BLOCK_SIZE, idx*IO_BLOCK_SIZE);
@ -991,20 +924,13 @@ int FilesOperation::fischl_link(const char *from, const char *to) {
//check path //check path
char *pathdup = strdup(to); char *pathdup = strdup(to);
char *lastSlash = strrchr(pathdup, '/'); char *lastSlash = strrchr(pathdup, '/');
*lastSlash = '\0'; // Split the string into parent path and new directory *lastSlash = '\0'; // Split the string into parent path and new directory name; <parent path>\0<direcotry name>
// name; <parent path>\0<direcotry name> char *newFilename = lastSlash+1; //\0<direcotry name>, get from <direcotry name>
char *newFilename = char *ParentPath = pathdup;//pathdup are separated by pathdup, so it take <parent path> only
lastSlash + 1; //\0<direcotry name>, get from <direcotry name> // fprintf(stderr,"[%s ,%d] ParentPath:%s, strlen=%d\n",__func__,__LINE__, ParentPath, strlen(ParentPath));
char *ParentPath = pathdup; // pathdup are separated by pathdup, so it take FileNode *parent_filenode = strlen(ParentPath)? fischl_load_entry(root_node, ParentPath): root_node->self_info;
// <parent path> only
// fprintf(stderr,"[%s ,%d] ParentPath:%s, strlen=%d\n",__func__,__LINE__,
// ParentPath, strlen(ParentPath));
FileNode *parent_filenode = strlen(ParentPath)
? fischl_load_entry(root_node, ParentPath)
: root_node->self_info;
if (parent_filenode == NULL) { if (parent_filenode == NULL) {
fprintf(stderr, "[%s ,%d] ParentPath:{%s} not found\n", __func__, __LINE__, fprintf(stderr,"[%s ,%d] ParentPath:{%s} not found\n",__func__,__LINE__, ParentPath);
ParentPath);
free(pathdup); free(pathdup);
return -1; return -1;
} }
@ -1019,15 +945,14 @@ int FilesOperation::fischl_link(const char *from, const char *to) {
ret.metadata.reference_count += 1; ret.metadata.reference_count += 1;
fs->inode_manager->save_inode(&ret); fs->inode_manager->save_inode(&ret);
fischl_add_entry(parent_filenode->subdirectory, ret.inode_num, newFilename, fischl_add_entry(parent_filenode->subdirectory, ret.inode_num, newFilename, &ret);
&ret);
free(pathdup); free(pathdup);
return 0; return 0;
} }
// TODO: rename dir and rename fail // TODO: rename dir and rename fail
int FilesOperation::fischl_rename(const char *old_path, const char *new_path, int FilesOperation::fischl_rename(const char *old_path, const char *new_path, unsigned int flags){
unsigned int flags) {
//find old path //find old path
char *pathdup = strdup(old_path); char *pathdup = strdup(old_path);
char *lastSlash = strrchr(pathdup, '/'); char *lastSlash = strrchr(pathdup, '/');
@ -1043,14 +968,10 @@ int FilesOperation::fischl_rename(const char *old_path, const char *new_path,
rename_info.exchangeExist = false; rename_info.exchangeExist = false;
rename_info.oldParentNode = fischl_load_entry(root_node, oldParentPath); rename_info.oldParentNode = fischl_load_entry(root_node, oldParentPath);
//if path end with / means to rename directory //if path end with / means to rename directory
rename_info.oldFileNode = rename_info.oldFileNode = strlen(filename)? fischl_load_entry(rename_info.oldParentNode->subdirectory, filename):rename_info.oldParentNode;
strlen(filename)
? fischl_load_entry(rename_info.oldParentNode->subdirectory, filename)
: rename_info.oldParentNode;
if (rename_info.oldFileNode == NULL) { if (rename_info.oldFileNode == NULL) {
fprintf(stderr, "[%s ,%d] path %s not found by fischl_load_entry\n", fprintf(stderr,"[%s ,%d] path %s not found by fischl_load_entry\n",__func__,__LINE__, old_path);
__func__, __LINE__, old_path);
free(pathdup); free(pathdup);
return -ENOENT; return -ENOENT;
} }
@ -1058,33 +979,23 @@ int FilesOperation::fischl_rename(const char *old_path, const char *new_path,
//find new path //find new path
char *new_pathdup = strdup(new_path); char *new_pathdup = strdup(new_path);
lastSlash = strrchr(new_pathdup, '/'); lastSlash = strrchr(new_pathdup, '/');
*lastSlash = '\0'; // Split the string into parent path and new directory *lastSlash = '\0'; // Split the string into parent path and new directory name; <parent path>\0<direcotry name>
// name; <parent path>\0<direcotry name> char *newParentPath = new_pathdup;//pathdup are separated by pathdup, so it take <parent path> only
char *newParentPath = new_pathdup; // pathdup are separated by pathdup, so it
// take <parent path> only
//put new path info in rename struct //put new path info in rename struct
rename_info.newName = rename_info.newName = lastSlash+1; //\0<direcotry name>, get from <direcotry name>
lastSlash + 1; //\0<direcotry name>, get from <direcotry name>
rename_info.newFileNode = fischl_load_entry(root_node, new_path); rename_info.newFileNode = fischl_load_entry(root_node, new_path);
rename_info.newParentNode = strlen(newParentPath) rename_info.newParentNode = strlen(newParentPath)? fischl_load_entry(root_node, newParentPath): root_node->self_info;
? fischl_load_entry(root_node, newParentPath)
: root_node->self_info;
if (!permission_check_by_inode_num(W_OK, if(!permission_check_by_inode_num(W_OK, rename_info.oldParentNode->inode_number)){
rename_info.oldParentNode->inode_number)) {
return -EACCES; return -EACCES;
} }
if (!permission_check_by_inode_num(W_OK, if(!permission_check_by_inode_num(W_OK, rename_info.newParentNode->inode_number)){
rename_info.newParentNode->inode_number)) {
return -EACCES; return -EACCES;
} }
if (!permission_check_by_inode_num(W_OK, if(!permission_check_by_inode_num(W_OK, rename_info.oldFileNode->inode_number)){
rename_info.oldFileNode->inode_number)) {
return -EACCES; return -EACCES;
} }
if (rename_info.newFileNode != NULL && if(rename_info.newFileNode != NULL && !permission_check_by_inode_num(W_OK, rename_info.newFileNode->inode_number)){
!permission_check_by_inode_num(W_OK,
rename_info.newFileNode->inode_number)) {
return -EACCES; return -EACCES;
} }
@ -1092,8 +1003,7 @@ int FilesOperation::fischl_rename(const char *old_path, const char *new_path,
if (flags & RENAME_NOREPLACE) { if (flags & RENAME_NOREPLACE) {
// Check if newpath exists and return error if it does // Check if newpath exists and return error if it does
if(rename_info.newFileNode != NULL){ if(rename_info.newFileNode != NULL){
fprintf(stderr, "[%s ,%d] newpath has already existed\n", __func__, fprintf(stderr,"[%s ,%d] newpath has already existed\n",__func__,__LINE__);
__LINE__);
free(new_pathdup);//new path free(new_pathdup);//new path
free(pathdup);//old path free(pathdup);//old path
return -1; return -1;
@ -1103,8 +1013,7 @@ int FilesOperation::fischl_rename(const char *old_path, const char *new_path,
if (flags & RENAME_EXCHANGE) { if (flags & RENAME_EXCHANGE) {
// Ensure both oldpath and newpath exist and exchange them atomically // Ensure both oldpath and newpath exist and exchange them atomically
if(rename_info.newFileNode == NULL){ if(rename_info.newFileNode == NULL){
fprintf(stderr, "[%s ,%d] newpath does not exist cannot exchange\n", fprintf(stderr,"[%s ,%d] newpath does not exist cannot exchange\n",__func__,__LINE__);
__func__, __LINE__);
free(new_pathdup); free(new_pathdup);
free(pathdup); free(pathdup);
return -1; return -1;
@ -1117,8 +1026,7 @@ int FilesOperation::fischl_rename(const char *old_path, const char *new_path,
bool change_flag = false; bool change_flag = false;
//delete record on old path //delete record on old path
for (u_int64_t idx = 0; idx < parent_INode.metadata.size / IO_BLOCK_SIZE; for (u_int64_t idx=0; idx<parent_INode.metadata.size/IO_BLOCK_SIZE; idx++) {
idx++) {
fs->read(&parent_INode, rw_buffer, IO_BLOCK_SIZE, idx*IO_BLOCK_SIZE); fs->read(&parent_INode, rw_buffer, IO_BLOCK_SIZE, idx*IO_BLOCK_SIZE);
DirectoryEntry ent; DirectoryEntry ent;
for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){ for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){
@ -1142,16 +1050,14 @@ int FilesOperation::fischl_rename(const char *old_path, const char *new_path,
change_flag = false; change_flag = false;
//delete record on old path //delete record on old path
for (u_int64_t idx = 0; idx < parent_INode.metadata.size / IO_BLOCK_SIZE; for (u_int64_t idx=0; idx<parent_INode.metadata.size/IO_BLOCK_SIZE; idx++) {
idx++) {
fs->read(&parent_INode, rw_buffer, IO_BLOCK_SIZE, idx*IO_BLOCK_SIZE); fs->read(&parent_INode, rw_buffer, IO_BLOCK_SIZE, idx*IO_BLOCK_SIZE);
DirectoryEntry ent; DirectoryEntry ent;
for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){ for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){
ent.deserialize(rw_buffer+i); ent.deserialize(rw_buffer+i);
if (ent.inode_number == rename_info.oldFileNode->inode_number) { if (ent.inode_number == rename_info.oldFileNode->inode_number) {
change_flag = true;//should be change change_flag = true;//should be change
strncpy(ent.file_name, rename_info.newName, strncpy(ent.file_name, rename_info.newName, sizeof(ent.file_name) - 1);
sizeof(ent.file_name) - 1);
ent.file_name[sizeof(ent.file_name) - 1] = '\0'; ent.file_name[sizeof(ent.file_name) - 1] = '\0';
ent.serialize(rw_buffer+i); ent.serialize(rw_buffer+i);
break; break;
@ -1163,10 +1069,8 @@ int FilesOperation::fischl_rename(const char *old_path, const char *new_path,
break; break;
} }
} }
unlink_inode(rename_info.oldFileNode->inode_number);
fischl_rm_entry(rename_info.oldParentNode->subdirectory, filename); fischl_rm_entry(rename_info.oldParentNode->subdirectory, filename);
fischl_rm_entry(rename_info.newParentNode->subdirectory, fischl_rm_entry(rename_info.newParentNode->subdirectory, rename_info.newName);
rename_info.newName);
return 0; return 0;
} }
@ -1174,6 +1078,7 @@ int FilesOperation::fischl_rename(const char *old_path, const char *new_path,
// Hard Disk rename // Hard Disk rename
if(rename_info.oldFileNode->subdirectory != NULL){//secure its directory if(rename_info.oldFileNode->subdirectory != NULL){//secure its directory
//remove its record from subdirectory; find .. from subdirectory //remove its record from subdirectory; find .. from subdirectory
} }
// remove its record from parent // remove its record from parent
INode_Data parent_INode; INode_Data parent_INode;
@ -1185,14 +1090,12 @@ int FilesOperation::fischl_rename(const char *old_path, const char *new_path,
INode_Data ret; INode_Data ret;
ret.inode_num = rename_info.oldFileNode->inode_number; ret.inode_num = rename_info.oldFileNode->inode_number;
fs->inode_manager->load_inode(&ret); fs->inode_manager->load_inode(&ret);
if (insert_inode_to(rename_info.newParentNode->inode_number, if(insert_inode_to(rename_info.newParentNode->inode_number, rename_info.newName, &ret, false)<0){
rename_info.newName, &ret, false) < 0) {
return -1; return -1;
} }
bool change_flag = false; bool change_flag = false;
//delete record on old path //delete record on old path
for (u_int64_t idx = 0; idx < parent_INode.metadata.size / IO_BLOCK_SIZE; for (u_int64_t idx=0; idx<parent_INode.metadata.size/IO_BLOCK_SIZE; idx++) {
idx++) {
fs->read(&parent_INode, rw_buffer, IO_BLOCK_SIZE, idx*IO_BLOCK_SIZE); fs->read(&parent_INode, rw_buffer, IO_BLOCK_SIZE, idx*IO_BLOCK_SIZE);
DirectoryEntry ent; DirectoryEntry ent;
for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){ for(int i=0;i<=IO_BLOCK_SIZE-264;i+=264){
@ -1211,10 +1114,6 @@ int FilesOperation::fischl_rename(const char *old_path, const char *new_path,
break; break;
} }
} }
if (rename_info.newParentNode != NULL) {
fischl_rm_entry(rename_info.newParentNode->subdirectory,
rename_info.newName);
}
fischl_rm_entry(rename_info.oldParentNode->subdirectory, filename); fischl_rm_entry(rename_info.oldParentNode->subdirectory, filename);
//free path //free path
@ -1241,8 +1140,6 @@ int FilesOperation::fischl_truncate(const char *path, off_t offset,
} }
res = fs->truncate(&inode, offset); res = fs->truncate(&inode, offset);
fs->inode_manager->save_inode(&inode); fs->inode_manager->save_inode(&inode);
if (res < 0)
return -errno;
return res; return res;
} }
@ -1265,8 +1162,7 @@ int FilesOperation::fischl_read(const char *path, char *buf, size_t size,
// Assuming inode is correctly initialized here based on 'path' // Assuming inode is correctly initialized here based on 'path'
inode.inode_num = fi->fh; inode.inode_num = fi->fh;
fs->inode_manager->load_inode(&inode); fs->inode_manager->load_inode(&inode);
// printf("OUT READ %llu %llu %llu\n", inode.inode_num, //printf("OUT READ %llu %llu %llu\n", inode.inode_num, inode.single_indirect_block, inode.double_indirect_block);
// inode.single_indirect_block, inode.double_indirect_block);
ssize_t bytes_read = fs->read(&inode, buf, size, offset); ssize_t bytes_read = fs->read(&inode, buf, size, offset);
//printf("BYTES_READ %d\n",int(bytes_read)); //printf("BYTES_READ %d\n",int(bytes_read));
//for (int i = 0; i < bytes_read; i++)printf("%x", buf[i]&0xff); //for (int i = 0; i < bytes_read; i++)printf("%x", buf[i]&0xff);
@ -1294,15 +1190,10 @@ int FilesOperation::fischl_read(const char *path, char *buf, size_t size,
buf, block_buffer); bytes_read += copy_size; block_index++; block_offset = 0; buf, block_buffer); bytes_read += copy_size; block_index++; block_offset = 0;
// Only the first block might have a non-zero offset // Only the first block might have a non-zero offset
}*/ }*/
if (bytes_read < 0)
return -errno;
return bytes_read; // Return the actual number of bytes read return bytes_read; // Return the actual number of bytes read
} }
int FilesOperation::fischl_utimens(const char *path, int FilesOperation::fischl_utimens(const char *path, const struct timespec tv[2], struct fuse_file_info *fi){
const struct timespec tv[2],
struct fuse_file_info *fi) {
(void) fi; (void) fi;
int res = 0; int res = 0;
u_int64_t fh = namei(path); u_int64_t fh = namei(path);
@ -1314,10 +1205,8 @@ int FilesOperation::fischl_utimens(const char *path,
INode_Data inode; INode_Data inode;
inode.inode_num = fh; inode.inode_num = fh;
fs->inode_manager->load_inode(&inode); fs->inode_manager->load_inode(&inode);
inode.metadata.access_time = inode.metadata.access_time = (u_int64_t)tv[0].tv_sec * 1000000000ULL + tv[0].tv_nsec;
(u_int64_t)tv[0].tv_sec * 1000000000ULL + tv[0].tv_nsec; inode.metadata.modification_time = (u_int64_t)tv[1].tv_sec * 1000000000ULL + tv[1].tv_nsec;
inode.metadata.modification_time =
(u_int64_t)tv[1].tv_sec * 1000000000ULL + tv[1].tv_nsec;
fs->inode_manager->save_inode(&inode); fs->inode_manager->save_inode(&inode);
return 0; return 0;
} }

View File

@ -35,7 +35,6 @@ static const struct fuse_opt option_spec[] = {
void* fischl_init(struct fuse_conn_info *conn, struct fuse_config *cfg) { void* fischl_init(struct fuse_conn_info *conn, struct fuse_config *cfg) {
cfg->use_ino = 1; cfg->use_ino = 1;
conn->want &= ~FUSE_CAP_ATOMIC_O_TRUNC;
options.fsop->initialize(options.load); options.fsop->initialize(options.load);
} }

View File

@ -52,10 +52,8 @@ int DataBlock_Manager_Bitmap::new_datablock(u_int64_t *block_num) {
char zero_buf[IO_BLOCK_SIZE] = {0}; char zero_buf[IO_BLOCK_SIZE] = {0};
if (bitmap_block_num < block_segment_start || if (bitmap_block_num < block_segment_start ||
bitmap_block_num >= block_segment_end) { bitmap_block_num >= block_segment_end)
perror("Error with new_datablock freelist head\n");
return -1; return -1;
}
if ((err = fs->disk->read_block(bitmap_block_num, bitmap.buf)) < 0) if ((err = fs->disk->read_block(bitmap_block_num, bitmap.buf)) < 0)
return err; return err;
@ -66,10 +64,8 @@ int DataBlock_Manager_Bitmap::new_datablock(u_int64_t *block_num) {
u_int64_t relative_block_num = bitmap.claim_relative_block(); u_int64_t relative_block_num = bitmap.claim_relative_block();
if (relative_block_num == 0) { if (relative_block_num == 0)
errno = ENOSPC;
return -1; return -1;
}
u_int64_t block_num_ = relative_block_num + bitmap_block_num; u_int64_t block_num_ = relative_block_num + bitmap_block_num;

View File

@ -31,8 +31,7 @@ int Fs::sweep_inode_datablocks(INode_Data *inode_data,
DatablockOperation *op) { DatablockOperation *op) {
int result; int result;
// printf("SWEEP %llu %llu %llu\n", inode_data->inode_num, //printf("SWEEP %llu %llu %llu\n", inode_data->inode_num, inode_data->single_indirect_block, inode_data->double_indirect_block);
// 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) {
@ -97,8 +96,7 @@ int Fs::sweep_datablocks(u_int64_t *block_num, int indirect_num,
} }
} }
// if((*block_num)>30000000000000LL)printf("DIES 1 %llu %d %llu\n", //if((*block_num)>30000000000000LL)printf("DIES 1 %llu %d %llu\n", *block_num, indirect_num, start_block_index);
// *block_num, indirect_num, start_block_index);
if (indirect_num == 0) { if (indirect_num == 0) {
bool delete_block = false; bool delete_block = false;
@ -177,8 +175,7 @@ public:
std::min(IO_BLOCK_SIZE - offset, count - bytes_completed); std::min(IO_BLOCK_SIZE - offset, count - bytes_completed);
if (block_num != 0) { if (block_num != 0) {
if ((block_num) > 3000000000000LL) if((block_num)>3000000000000LL)printf("DIES 2\n");
printf("DIES 2\n");
if ((err = fs->disk->read_block(block_num, datablock_buf)) < 0) if ((err = fs->disk->read_block(block_num, datablock_buf)) < 0)
return err; return err;
@ -208,8 +205,7 @@ public:
std::min(IO_BLOCK_SIZE - offset, count - bytes_completed); std::min(IO_BLOCK_SIZE - offset, count - bytes_completed);
if (write_size < IO_BLOCK_SIZE){ if (write_size < IO_BLOCK_SIZE){
if ((block_num) > 3000000000000LL) if((block_num)>3000000000000LL)printf("DIES 3\n");
printf("DIES 3\n");
if ((err = fs->disk->read_block(block_num, datablock_buf)) < 0) if ((err = fs->disk->read_block(block_num, datablock_buf)) < 0)
return err; return err;
} }
@ -239,8 +235,7 @@ public:
(*delete_block) = true; (*delete_block) = true;
return 1; return 1;
} }
if ((block_num) > 3000000000000LL) if((block_num)>3000000000000LL)printf("DIES 4\n");
printf("DIES 4\n");
if ((err = fs->disk->read_block(block_num, datablock_buf)) < 0) if ((err = fs->disk->read_block(block_num, datablock_buf)) < 0)
return err; return err;
@ -294,10 +289,9 @@ ssize_t Fs::read(INode_Data *inode_data, char buf[], size_t count,
op.bytes_completed = 0; op.bytes_completed = 0;
op.fs = this; op.fs = this;
// printf("IN READ %llu %llu %llu\n", inode_data->inode_num, //printf("IN READ %llu %llu %llu\n", inode_data->inode_num, inode_data->single_indirect_block, inode_data->double_indirect_block);
// inode_data->single_indirect_block, inode_data->double_indirect_block);
if ((err = sweep_inode_datablocks(inode_data, start_block_index, false, if ((err = sweep_inode_datablocks(inode_data, start_block_index, false,
&op)) < 0) &op)) != 0)
return err; return err;
return op.bytes_completed; return op.bytes_completed;
@ -307,11 +301,6 @@ ssize_t Fs::write(INode_Data *inode_data, const char buf[], size_t count,
size_t offset) { size_t offset) {
int err; int err;
if (count + offset > FILE_SIZE_MAX) {
errno = EFBIG;
return -1;
}
u_int64_t start_block_index = offset / IO_BLOCK_SIZE; u_int64_t start_block_index = offset / IO_BLOCK_SIZE;
size_t internal_offset = offset - (start_block_index * IO_BLOCK_SIZE); size_t internal_offset = offset - (start_block_index * IO_BLOCK_SIZE);
@ -322,8 +311,8 @@ ssize_t Fs::write(INode_Data *inode_data, const char buf[], size_t count,
op.bytes_completed = 0; op.bytes_completed = 0;
op.fs = this; op.fs = this;
if ((err = sweep_inode_datablocks(inode_data, start_block_index, true, &op)) < if ((err = sweep_inode_datablocks(inode_data, start_block_index, true,
0) &op)) != 0)
return err; return err;
inode_data->metadata.size = inode_data->metadata.size =
@ -332,19 +321,9 @@ ssize_t Fs::write(INode_Data *inode_data, const char buf[], size_t count,
return op.bytes_completed; return op.bytes_completed;
} }
int Fs::truncate(INode_Data *inode_data, off_t length) { int Fs::truncate(INode_Data *inode_data, size_t length) {
int err; int err;
if (length > FILE_SIZE_MAX) {
errno = EFBIG;
return -1;
}
if (length < 0) {
errno = EINVAL;
return -1;
}
u_int64_t start_block_index = length / IO_BLOCK_SIZE; u_int64_t start_block_index = length / IO_BLOCK_SIZE;
size_t internal_offset = length - (start_block_index * IO_BLOCK_SIZE); size_t internal_offset = length - (start_block_index * IO_BLOCK_SIZE);
@ -364,10 +343,8 @@ int Fs::truncate(INode_Data *inode_data, off_t length) {
ssize_t Fs::lseek_next_data(INode_Data *inode_data, size_t offset) { ssize_t Fs::lseek_next_data(INode_Data *inode_data, size_t offset) {
int err; int err;
if (offset >= inode_data->metadata.size) { if (offset >= inode_data->metadata.size)
errno = ENXIO;
return -1; return -1;
}
u_int64_t start_block_index = offset / IO_BLOCK_SIZE; u_int64_t start_block_index = offset / IO_BLOCK_SIZE;
size_t internal_offset = offset - (start_block_index * IO_BLOCK_SIZE); size_t internal_offset = offset - (start_block_index * IO_BLOCK_SIZE);
@ -382,10 +359,8 @@ ssize_t Fs::lseek_next_data(INode_Data *inode_data, size_t offset) {
&op)) < 0) &op)) < 0)
return err; return err;
if (op.bytes_completed >= inode_data->metadata.size) { if (op.bytes_completed >= inode_data->metadata.size)
errno = ENXIO;
return -1; return -1;
}
return op.bytes_completed; return op.bytes_completed;
} }
@ -393,10 +368,8 @@ ssize_t Fs::lseek_next_data(INode_Data *inode_data, size_t offset) {
ssize_t Fs::lseek_next_hole(INode_Data *inode_data, size_t offset) { ssize_t Fs::lseek_next_hole(INode_Data *inode_data, size_t offset) {
int err; int err;
if (offset >= inode_data->metadata.size) { if (offset >= inode_data->metadata.size)
errno = ENXIO;
return -1; return -1;
}
u_int64_t start_block_index = offset / IO_BLOCK_SIZE; u_int64_t start_block_index = offset / IO_BLOCK_SIZE;
size_t internal_offset = offset - (start_block_index * IO_BLOCK_SIZE); size_t internal_offset = offset - (start_block_index * IO_BLOCK_SIZE);

View File

@ -65,7 +65,6 @@ int RealRawDisk::read_block(u_int64_t block_number, char *buffer) {
if (lseek(fd, offset, SEEK_SET) == (u_int64_t)-1) { if (lseek(fd, offset, SEEK_SET) == (u_int64_t)-1) {
printf("LSEEK ERROR %llu %llu\n", block_number, offset); printf("LSEEK ERROR %llu %llu\n", block_number, offset);
perror("Error seeking to offset"); perror("Error seeking to offset");
errno = EIO;
return -1; return -1;
} }
@ -76,7 +75,6 @@ int RealRawDisk::read_block(u_int64_t block_number, char *buffer) {
//printf("\n"); //printf("\n");
if (bytesRead < IO_BLOCK_SIZE) { if (bytesRead < IO_BLOCK_SIZE) {
perror("Error reading from device"); perror("Error reading from device");
errno = EIO;
return -1; return -1;
} }
@ -88,7 +86,6 @@ int RealRawDisk::write_block(u_int64_t block_number, char *buffer) {
if (lseek(fd, offset, SEEK_SET) == (u_int64_t)-1) { if (lseek(fd, offset, SEEK_SET) == (u_int64_t)-1) {
perror("Error seeking to offset"); perror("Error seeking to offset");
errno = EIO;
return -1; return -1;
} }
@ -96,7 +93,6 @@ int RealRawDisk::write_block(u_int64_t block_number, char *buffer) {
ssize_t bytesWritten = write(fd, buffer, IO_BLOCK_SIZE); ssize_t bytesWritten = write(fd, buffer, IO_BLOCK_SIZE);
if (bytesWritten < IO_BLOCK_SIZE) { if (bytesWritten < IO_BLOCK_SIZE) {
perror("Error writing to device"); perror("Error writing to device");
errno = EIO;
return -1; return -1;
} }
@ -122,7 +118,6 @@ int FakeRawDisk::read_block(u_int64_t block_number, char *buffer) {
if (offset + IO_BLOCK_SIZE > diskSize) { if (offset + IO_BLOCK_SIZE > diskSize) {
perror("Error reading past fake disk size"); perror("Error reading past fake disk size");
errno = EIO;
return -1; return -1;
} }
@ -136,7 +131,6 @@ int FakeRawDisk::write_block(u_int64_t block_number, char *buffer) {
if (offset + IO_BLOCK_SIZE > diskSize) { if (offset + IO_BLOCK_SIZE > diskSize) {
perror("Error writing past fake disk size"); perror("Error writing past fake disk size");
errno = EIO;
return -1; return -1;
} }