From f5b572fa8c93495e9311ff5a5ca1c30664a8bae8 Mon Sep 17 00:00:00 2001 From: Victor Date: Fri, 24 Nov 2023 23:56:19 -0800 Subject: [PATCH] implement open,release,read and pass read test; write under construct --- include/files.h | 5 ++- lib/files.cpp | 82 +++++++++++++++++++++++++++++++++++++++++ test/layer2_API_dir.cpp | 7 ++++ 3 files changed, 93 insertions(+), 1 deletion(-) diff --git a/include/files.h b/include/files.h index f3cd1f0..f87e317 100644 --- a/include/files.h +++ b/include/files.h @@ -25,5 +25,8 @@ class FilesOperation { 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_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 *); }; \ No newline at end of file diff --git a/lib/files.cpp b/lib/files.cpp index 35efd3f..9f6027f 100644 --- a/lib/files.cpp +++ b/lib/files.cpp @@ -411,4 +411,86 @@ int FilesOperation::fischl_unlink(const char* path) { delete pathdup; 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 } \ No newline at end of file diff --git a/test/layer2_API_dir.cpp b/test/layer2_API_dir.cpp index 8de0cad..4b87f89 100644 --- a/test/layer2_API_dir.cpp +++ b/test/layer2_API_dir.cpp @@ -126,6 +126,13 @@ TEST(FileOperationTest, ReadTest) { fsop->read_datablock(inode, 0, read_buffer); 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 get_file_inum= fsop->namei("/foo/bar/baz"); inode.inode_construct(get_file_inum, *H);