diff --git a/clients/filesystem-fuse/src/filesystem.rs b/clients/filesystem-fuse/src/filesystem.rs index 307b56f0845..3f2f3e4b323 100644 --- a/clients/filesystem-fuse/src/filesystem.rs +++ b/clients/filesystem-fuse/src/filesystem.rs @@ -19,39 +19,41 @@ use fuse3::{Errno, FileType, Timestamp}; use std::time::SystemTime; +pub type Result = std::result::Result; + /// File system interface for the file system implementation. it use by FuseApiHandle /// the `file_id` and `parent_file_id` it is the unique identifier for the file system, it is used to identify the file or directory /// the `fh` it is the file handle, it is used to identify the opened file, it is used to read or write the file content pub trait IFileSystem: Send + Sync { fn get_file_path(&self, file_id: u64) -> String; - fn get_opened_file(&self, file_id: u64, fh: u64) -> Option; + fn get_opened_file(&self, file_id: u64, fh: u64) -> Result; - fn stat(&self, file_id: u64) -> Option; + fn stat(&self, file_id: u64) -> Result; - fn lookup(&self, parent_file_id: u64, name: &str) -> Option; + fn lookup(&self, parent_file_id: u64, name: &str) -> Result; - fn read_dir(&self, dir_file_id: u64) -> Vec; + fn read_dir(&self, dir_file_id: u64) -> Result>; - fn open_file(&self, file_id: u64) -> Result; + fn open_file(&self, file_id: u64) -> Result; - fn create_file(&self, parent_file_id: u64, name: &str) -> Result; + fn create_file(&self, parent_file_id: u64, name: &str) -> Result; - fn create_dir(&self, parent_file_id: u64, name: &str) -> Result; + fn create_dir(&self, parent_file_id: u64, name: &str) -> Result; - fn set_attr(&self, file_id: u64, file_stat: &FileStat) -> Result<(), Errno>; + fn set_attr(&self, file_id: u64, file_stat: &FileStat) -> Result<()>; - fn update_file_status(&self, file_id: u64, file_stat: &FileStat); + fn update_file_status(&self, file_id: u64, file_stat: &FileStat) -> Result<()>; fn read(&self, file_id: u64, fh: u64) -> Box; fn write(&self, file_id: u64, fh: u64) -> Box; - fn remove_file(&self, parent_file_id: u64, name: &str) -> Result<(), Errno>; + fn remove_file(&self, parent_file_id: u64, name: &str) -> Result<()>; - fn remove_dir(&self, parent_file_id: u64, name: &str) -> Result<(), Errno>; + fn remove_dir(&self, parent_file_id: u64, name: &str) -> Result<()>; - fn close_file(&self, file_id: u64, fh: u64) -> Result<(), Errno>; + fn close_file(&self, file_id: u64, fh: u64) -> Result<()>; } pub struct FileSystemContext { diff --git a/clients/filesystem-fuse/src/fuse_api_handle.rs b/clients/filesystem-fuse/src/fuse_api_handle.rs index 26b78db80d7..d53aa2900e6 100644 --- a/clients/filesystem-fuse/src/fuse_api_handle.rs +++ b/clients/filesystem-fuse/src/fuse_api_handle.rs @@ -72,24 +72,19 @@ impl FuseApiHandle { size: Option, atime: Option, mtime: Option, - ) -> Option { - let file_stat = self.local_fs.stat(inode); - match file_stat { - Some(f) => { - let mut nf = FileStat::clone(&f); - size.map(|size| { - nf.size = size; - }); - atime.map(|atime| { - nf.atime = atime; - }); - mtime.map(|mtime| { - nf.mtime = mtime; - }); - Some(nf) - } - _ => None, - } + ) -> Result { + let file_stat = self.local_fs.stat(inode)?; + let mut nf = FileStat::clone(&file_stat); + size.map(|size| { + nf.size = size; + }); + atime.map(|atime| { + nf.atime = atime; + }); + mtime.map(|mtime| { + nf.mtime = mtime; + }); + Ok(nf) } } @@ -108,16 +103,12 @@ impl Filesystem for FuseApiHandle { parent: Inode, name: &OsStr, ) -> fuse3::Result { - let file_stat = self.local_fs.lookup(parent, name.to_str().unwrap()); - - match file_stat { - Some(f) => Ok(ReplyEntry { - ttl: self.default_ttl, - attr: fstat_to_file_attr(&f, &self.fs_context), - generation: 0, - }), - None => Err(libc::ENOENT.into()), - } + let file_stat = self.local_fs.lookup(parent, name.to_str().unwrap())?; + Ok(ReplyEntry { + ttl: self.default_ttl, + attr: fstat_to_file_attr(&file_stat, &self.fs_context), + generation: 0, + }) } async fn getattr( @@ -128,20 +119,18 @@ impl Filesystem for FuseApiHandle { _flags: u32, ) -> fuse3::Result { // check the opened file inode is the same as the inode - if let Some(f) = fh.and_then(|fh| self.local_fs.get_opened_file(inode, fh)) { - if f.file_id != inode { + if let Some(fh) = fh { + let opened_file = self.local_fs.get_opened_file(inode, fh)?; + if opened_file.file_id != inode { return Err(libc::EBADF.into()); } } - let file_stat = self.local_fs.stat(inode); - match file_stat { - Some(f) => Ok(ReplyAttr { - ttl: self.default_ttl, - attr: fstat_to_file_attr(&f, &self.fs_context), - }), - None => Err(libc::ENOENT.into()), - } + let file_stat = self.local_fs.stat(inode)?; + Ok(ReplyAttr { + ttl: self.default_ttl, + attr: fstat_to_file_attr(&file_stat, &self.fs_context), + }) } async fn setattr( @@ -152,18 +141,13 @@ impl Filesystem for FuseApiHandle { set_attr: SetAttr, ) -> fuse3::Result { let new_file_stat = - self.get_modified_file_stat(inode, set_attr.size, set_attr.atime, set_attr.mtime); - match new_file_stat { - Some(stat) => { - let attr = fstat_to_file_attr(&stat, &self.fs_context); - self.local_fs.set_attr(inode, &stat); - Ok(ReplyAttr { - ttl: self.default_ttl, - attr: attr, - }) - } - None => Err(libc::ENOENT.into()), - } + self.get_modified_file_stat(inode, set_attr.size, set_attr.atime, set_attr.mtime)?; + let attr = fstat_to_file_attr(&new_file_stat, &self.fs_context); + self.local_fs.set_attr(inode, &new_file_stat)?; + Ok(ReplyAttr { + ttl: self.default_ttl, + attr: attr, + }) } async fn mkdir( @@ -300,11 +284,11 @@ impl Filesystem for FuseApiHandle { ) -> fuse3::Result>> { let current = self.local_fs.stat(parent); let current = match current { - Some(file) => file, - None => return Err(libc::ENOENT.into()), + Ok(file) => file, + Err(e) => return Err(e), }; - let files = self.local_fs.read_dir(parent); + let files = self.local_fs.read_dir(parent)?; let entries_stream = stream::iter(files.into_iter().enumerate().map(|(index, file_stat)| { Ok(DirectoryEntry { @@ -383,13 +367,8 @@ impl Filesystem for FuseApiHandle { offset: u64, lock_owner: u64, ) -> fuse3::Result>> { - let current = self.local_fs.stat(parent); - let current = match current { - Some(file) => file, - None => return Err(libc::ENOENT.into()), - }; - - let files = self.local_fs.read_dir(parent); + let current = self.local_fs.stat(parent)?; + let files = self.local_fs.read_dir(parent)?; let entries_stream = stream::iter(files.into_iter().enumerate().map(|(index, file_stat)| { Ok(DirectoryEntryPlus { diff --git a/clients/filesystem-fuse/src/memory_filesystem.rs b/clients/filesystem-fuse/src/memory_filesystem.rs index e93ce1f8aaf..7a47bdd0886 100644 --- a/clients/filesystem-fuse/src/memory_filesystem.rs +++ b/clients/filesystem-fuse/src/memory_filesystem.rs @@ -17,10 +17,9 @@ * under the License. */ use crate::file_handle_manager::FileHandleManager; -use crate::filesystem::{FileReader, FileStat, FileWriter, IFileSystem, OpenedFile}; +use crate::filesystem::{FileReader, FileStat, FileWriter, IFileSystem, OpenedFile, Result}; use crate::filesystem_metadata::{DefaultFileSystemMetadata, IFileSystemMetadata}; use dashmap::DashMap; -use fuse3::Errno; use std::sync::{Arc, Mutex, RwLock}; // MemoryFileSystem is a simple in-memory filesystem implementation @@ -71,27 +70,28 @@ impl IFileSystem for MemoryFileSystem { meta.get_file_path(file_id) } - fn get_opened_file(&self, _file_id: u64, fh: u64) -> Option { + fn get_opened_file(&self, _file_id: u64, fh: u64) -> Result { let file_handle_map = self.file_handle_manager.read().unwrap(); - file_handle_map.get_file(fh) + file_handle_map.get_file(fh).ok_or(libc::ENOENT.into()) } - fn stat(&self, file_id: u64) -> Option { + fn stat(&self, file_id: u64) -> Result { let meta = self.meta.read().unwrap(); - meta.get_file(file_id) + meta.get_file(file_id).ok_or(libc::ENOENT.into()) } - fn lookup(&self, parent_file_id: u64, name: &str) -> Option { + fn lookup(&self, parent_file_id: u64, name: &str) -> Result { let meta = self.meta.read().unwrap(); meta.get_file_from_dir(parent_file_id, name) + .ok_or(libc::ENOENT.into()) } - fn read_dir(&self, file_id: u64) -> Vec { + fn read_dir(&self, file_id: u64) -> Result> { let meta = self.meta.read().unwrap(); - meta.get_dir_childs(file_id) + Ok(meta.get_dir_childs(file_id)) } - fn open_file(&self, file_id: u64) -> Result { + fn open_file(&self, file_id: u64) -> Result { let meta = self.meta.read().unwrap(); let file_stat = meta.get_file(file_id); match file_stat { @@ -104,7 +104,7 @@ impl IFileSystem for MemoryFileSystem { } } - fn create_file(&self, parent_file_id: u64, name: &str) -> Result { + fn create_file(&self, parent_file_id: u64, name: &str) -> Result { let mut meta = self.meta.write().unwrap(); let file_stat = meta.add_file(parent_file_id, name); @@ -116,7 +116,7 @@ impl IFileSystem for MemoryFileSystem { Ok(file_handle) } - fn create_dir(&self, parent_file_id: u64, name: &str) -> Result { + fn create_dir(&self, parent_file_id: u64, name: &str) -> Result { let mut meta = self.meta.write().unwrap(); let file_stat = meta.add_dir(parent_file_id, name); @@ -125,13 +125,13 @@ impl IFileSystem for MemoryFileSystem { Ok(file_handle) } - fn set_attr(&self, file_id: u64, file_info: &FileStat) -> Result<(), Errno> { + fn set_attr(&self, file_id: u64, file_info: &FileStat) -> Result<()> { Ok(()) } - fn update_file_status(&self, file_id: u64, file_stat: &FileStat) { + fn update_file_status(&self, file_id: u64, file_stat: &FileStat) -> Result<()> { let mut meta = self.meta.write().unwrap(); - meta.update_file_stat(file_id, file_stat) + Ok(meta.update_file_stat(file_id, file_stat)) } fn read(&self, file_id: u64, fh: u64) -> Box { @@ -162,18 +162,18 @@ impl IFileSystem for MemoryFileSystem { }) } - fn remove_file(&self, parent_file_id: u64, name: &str) -> Result<(), Errno> { + fn remove_file(&self, parent_file_id: u64, name: &str) -> Result<()> { let mut meta = self.meta.write().unwrap(); meta.remove_file(parent_file_id, name); Ok(()) } - fn remove_dir(&self, parent_file_id: u64, name: &str) -> Result<(), Errno> { + fn remove_dir(&self, parent_file_id: u64, name: &str) -> Result<()> { let mut meta = self.meta.write().unwrap(); meta.remove_dir(parent_file_id, name) } - fn close_file(&self, _file_id: u64, fh: u64) -> Result<(), Errno> { + fn close_file(&self, _file_id: u64, fh: u64) -> Result<()> { let mut file_handle_manager = self.file_handle_manager.write().unwrap(); file_handle_manager.remove_file(fh); Ok(())