implement open,release,read and pass read test; write under construct

This commit is contained in:
Victor 2023-11-24 23:56:19 -08:00
parent 39d6ab26ff
commit f5b572fa8c
3 changed files with 93 additions and 1 deletions

View File

@ -25,5 +25,8 @@ class FilesOperation {
int fischl_create(const char *, mode_t, struct fuse_file_info *);//for regular file int fischl_create(const char *, mode_t, struct fuse_file_info *);//for regular file
//int fischl_readdir(const char *, void *, fuse_fill_dir_t, off_t, struct fuse_file_info *, enum fuse_readdir_flags); //int fischl_readdir(const char *, void *, fuse_fill_dir_t, off_t, struct fuse_file_info *, enum fuse_readdir_flags);
int fischl_unlink (const char *); int fischl_unlink (const char *);
//int fischl_open (const char *, struct fuse_file_info *); 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 *);
int fischl_read(const char *, char *, size_t, off_t, struct fuse_file_info *);
}; };

View File

@ -411,4 +411,86 @@ int FilesOperation::fischl_unlink(const char* path) {
delete pathdup; delete pathdup;
return -1; return -1;
} }
}
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 the kernel.
if no files will use create function
*/
FileNode *get_file;
if((get_file = fischl_find_entry(root_node, path)) == NULL)
return -ENOENT;
//if need to do with flag fi->flags ((fi->flags & O_ACCMODE)). Initial setting ALL access
//create function will handle file descriptor fi->fh
fi->fh = get_file->inode_number;
return 0;//SUCESS
}
int FilesOperation::fischl_release(const char *path, struct fuse_file_info *fi){
/*Creation (O_CREAT, O_EXCL, O_NOCTTY) flags will be filtered out / handled by the kernel.
if no files will use create function
*/
FileNode *get_file;
if((get_file = fischl_find_entry(root_node, path)) == NULL)
return -ENOENT;
//do with file descriptor that cannot be used
fi->fh = -1;
return 0;//SUCESS
}
int FilesOperation::fischl_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi){
/** Write data to an open file
*
* Write should return exactly the number of bytes requested
* except on error. An exception to this is when the 'direct_io'
* mount option is specified (see read operation).
*
* Unless FUSE_CAP_HANDLE_KILLPRIV is disabled, this method is
* expected to reset the setuid and setgid bits.
*/
// use path for debug, filedescriptor is enough
// FileNode *get_file;
// if((get_file = fischl_find_entry(root_node, path)) == NULL)
// return -ENOENT;
return size;
}
int FilesOperation::fischl_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi){
/** Read data from an open file
*
* Read should return exactly the number of bytes requested except
* on EOF or error, otherwise the rest of the data will be
* substituted with zeroes. An exception to this is when the
* 'direct_io' mount option is specified, in which case the return
* value of the read system call will reflect the return value of
* this operation.
*/
// Caution! this based on content in file are multiple of IO_BLOCK_SIZE, not the exact write size.
// based on current read_datablock API implement, when read_datablock pass with actual size not index this function should be fixed
INode inode;
// Assuming inode is correctly initialized here based on 'path'
inode.inode_construct(fi->fh, disk);
size_t len = inode.size * IO_BLOCK_SIZE; // Assuming each block is 4096 bytes
if (offset >= len) return 0; // Offset is beyond the end of the file
if (offset + size > len) size = len - offset; // Adjust size if it goes beyond EOF
size_t bytes_read = 0;
size_t block_index = offset / IO_BLOCK_SIZE; // Starting block index
size_t block_offset = offset % IO_BLOCK_SIZE; // Offset within the first block
// fprintf(stderr,"[%s ,%d] inode.size %d\n",__func__,__LINE__, inode.size);
while (bytes_read < size && block_index < inode.size) {
char block_buffer[IO_BLOCK_SIZE]; // Temporary buffer for each block
read_datablock(inode, block_index, block_buffer);
// fprintf(stderr,"[%s ,%d] block_index %d\n",__func__,__LINE__, block_index);
size_t copy_size = std::min(size - bytes_read, IO_BLOCK_SIZE - block_offset);
memcpy(buf + bytes_read, block_buffer + block_offset, copy_size);
// fprintf(stderr,"[%s ,%d] buf %s, block_buffer %s\n",__func__,__LINE__, buf, block_buffer);
bytes_read += copy_size;
block_index++;
block_offset = 0; // Only the first block might have a non-zero offset
}
return bytes_read; // Return the actual number of bytes read
} }

View File

@ -126,6 +126,13 @@ TEST(FileOperationTest, ReadTest) {
fsop->read_datablock(inode, 0, read_buffer); fsop->read_datablock(inode, 0, read_buffer);
EXPECT_EQ(read_buffer[0], '1'); EXPECT_EQ(read_buffer[0], '1');
//read test file again with fischl_read API
struct fuse_file_info fi;
fsop->fischl_open("/test", &fi);
EXPECT_EQ(fi.fh, get_file_inum);
fsop->fischl_read("/test", read_buffer, sizeof(read_buffer), 0, &fi);
EXPECT_EQ(read_buffer[0], '1');
//read baz file //read baz file
get_file_inum= fsop->namei("/foo/bar/baz"); get_file_inum= fsop->namei("/foo/bar/baz");
inode.inode_construct(get_file_inum, *H); inode.inode_construct(get_file_inum, *H);