From b0b03ad6ce056670654482df6a842b192e77be89 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sat, 6 Jan 2024 09:50:19 +0000 Subject: [PATCH] add comments and extend support of meta information - add functions to determine the file type and the file size --- src/fs/fuse.rs | 12 ++++++++++++ src/fs/mem.rs | 20 ++++++++++---------- src/fs/mod.rs | 31 ++++++++++++++++++++++++++----- 3 files changed, 48 insertions(+), 15 deletions(-) diff --git a/src/fs/fuse.rs b/src/fs/fuse.rs index f0fe16419a..a994a21363 100644 --- a/src/fs/fuse.rs +++ b/src/fs/fuse.rs @@ -187,20 +187,32 @@ unsafe impl FuseOut for fuse_entry_out {} #[repr(C)] #[derive(Default, Debug)] struct fuse_attr { + /// inode number pub ino: u64, + /// size in bytes pub size: u64, + /// size in blocks pub blocks: u64, + /// time of last access pub atime: u64, + /// time of last modification pub mtime: u64, + /// time of last status change pub ctime: u64, pub atimensec: u32, pub mtimensec: u32, pub ctimensec: u32, + /// access permissions pub mode: u32, + /// number of hard links pub nlink: u32, + /// user id pub uid: u32, + /// group id pub gid: u32, + /// device id pub rdev: u32, + /// block size pub blksize: u32, pub padding: u32, } diff --git a/src/fs/mem.rs b/src/fs/mem.rs index 30a56bb935..dc23653f21 100644 --- a/src/fs/mem.rs +++ b/src/fs/mem.rs @@ -148,7 +148,7 @@ impl Clone for RamFileInterface { } } -#[derive(Debug, Clone)] +#[derive(Debug)] pub(crate) struct RomFile { data: Arc>, attr: FileAttr, @@ -171,7 +171,7 @@ impl VfsNode for RomFile { fn traverse_lstat(&self, components: &mut Vec<&str>) -> Result { if components.is_empty() { - Ok(self.attr) + self.get_file_attributes() } else { Err(IoError::EBADF) } @@ -179,7 +179,7 @@ impl VfsNode for RomFile { fn traverse_stat(&self, components: &mut Vec<&str>) -> Result { if components.is_empty() { - Ok(self.attr) + self.get_file_attributes() } else { Err(IoError::EBADF) } @@ -193,7 +193,7 @@ impl RomFile { slice::from_raw_parts(ptr, length) })), attr: FileAttr { - st_mode: mode, + st_mode: mode | AccessPermission::S_IFREG, ..Default::default() }, } @@ -223,7 +223,7 @@ impl VfsNode for RamFile { fn traverse_lstat(&self, components: &mut Vec<&str>) -> Result { if components.is_empty() { - Ok(self.attr) + self.get_file_attributes() } else { Err(IoError::EBADF) } @@ -231,7 +231,7 @@ impl VfsNode for RamFile { fn traverse_stat(&self, components: &mut Vec<&str>) -> Result { if components.is_empty() { - Ok(self.attr) + self.get_file_attributes() } else { Err(IoError::EBADF) } @@ -243,7 +243,7 @@ impl RamFile { Self { data: Arc::new(RwSpinLock::new(Vec::new())), attr: FileAttr { - st_mode: mode, + st_mode: mode | AccessPermission::S_IFREG, ..Default::default() }, } @@ -263,7 +263,7 @@ impl MemDirectory { Self { inner: Arc::new(RwSpinLock::new(BTreeMap::new())), attr: FileAttr { - st_mode: mode, + st_mode: mode | AccessPermission::S_IFDIR, ..Default::default() }, } @@ -392,7 +392,7 @@ impl VfsNode for MemDirectory { if components.is_empty() { if let Some(node) = self.inner.read().get(&node_name) { - node.get_file_attributes()?; + return node.get_file_attributes(); } } @@ -412,7 +412,7 @@ impl VfsNode for MemDirectory { if components.is_empty() { if let Some(node) = self.inner.read().get(&node_name) { - node.get_file_attributes()?; + return node.get_file_attributes(); } } diff --git a/src/fs/mod.rs b/src/fs/mod.rs index b0eab13e77..4fda81e36f 100644 --- a/src/fs/mod.rs +++ b/src/fs/mod.rs @@ -307,17 +307,27 @@ pub struct FileAttr { pub st_dev: u64, pub st_ino: u64, pub st_nlink: u64, + /// access permissions pub st_mode: AccessPermission, + /// user id pub st_uid: u32, + /// group id pub st_gid: u32, + /// device id pub st_rdev: u64, + /// size in bytes pub st_size: i64, + /// block size pub st_blksize: i64, + /// size in blocks pub st_blocks: i64, + /// time of last access pub st_atime: i64, pub st_atime_nsec: i64, + /// time of last modification pub st_mtime: i64, pub st_mtime_nsec: i64, + /// time of last status change pub st_ctime: i64, pub st_ctime_nsec: i64, } @@ -414,14 +424,25 @@ pub fn file_attributes(path: &str) -> Result { pub struct Metadata(FileAttr); impl Metadata { - pub fn new(attr: FileAttr) -> Self { - Self(attr) - } - /// Returns the size of the file, in bytes pub fn len(&self) -> usize { self.0.st_size.try_into().unwrap() } + + /// Returns true if this metadata is for a file. + pub fn is_file(&self) -> bool { + self.0.st_mode.contains(AccessPermission::S_IFREG) + } + + /// Returns true if this metadata is for a directory. + pub fn is_dir(&self) -> bool { + self.0.st_mode.contains(AccessPermission::S_IFDIR) + } +} + +/// Given a path, query the file system to get information about a file, directory, etc. +pub fn metadata(path: &str) -> Result { + Ok(Metadata(file_attributes(path)?)) } #[derive(Debug)] @@ -464,7 +485,7 @@ impl File { } pub fn metadata(&self) -> Result { - Ok(Metadata::new(file_attributes(&self.path)?)) + metadata(&self.path) } }