diff options
Diffstat (limited to 'tvix')
-rw-r--r-- | tvix/castore/src/fs/file_attr.rs | 26 | ||||
-rw-r--r-- | tvix/castore/src/fs/inodes.rs | 37 | ||||
-rw-r--r-- | tvix/castore/src/fs/mod.rs | 40 |
3 files changed, 46 insertions, 57 deletions
diff --git a/tvix/castore/src/fs/file_attr.rs b/tvix/castore/src/fs/file_attr.rs index ad41f036a253..2e0e70e3cdae 100644 --- a/tvix/castore/src/fs/file_attr.rs +++ b/tvix/castore/src/fs/file_attr.rs @@ -1,5 +1,5 @@ #![allow(clippy::unnecessary_cast)] // libc::S_IFDIR is u32 on Linux and u16 on MacOS -use super::inodes::{DirectoryInodeData, InodeData}; + use fuse_backend_rs::abi::fuse_abi::Attr; /// The [Attr] describing the root @@ -27,27 +27,3 @@ pub const ROOT_FILE_ATTR: Attr = Attr { #[cfg(target_os = "macos")] padding: 0, }; - -/// for given &Node and inode, construct an [Attr] -pub fn gen_file_attr(inode_data: &InodeData, inode: u64) -> Attr { - Attr { - ino: inode, - // FUTUREWORK: play with this numbers, as it affects read sizes for client applications. - blocks: 1024, - size: match inode_data { - InodeData::Regular(_, size, _) => *size as u64, - InodeData::Symlink(target) => target.len() as u64, - InodeData::Directory(DirectoryInodeData::Sparse(_, size)) => *size as u64, - InodeData::Directory(DirectoryInodeData::Populated(_, ref children)) => { - children.len() as u64 - } - }, - mode: match inode_data { - InodeData::Regular(_, _, false) => libc::S_IFREG as u32 | 0o444, // no-executable files - InodeData::Regular(_, _, true) => libc::S_IFREG as u32 | 0o555, // executable files - InodeData::Symlink(_) => libc::S_IFLNK as u32 | 0o444, - InodeData::Directory(_) => libc::S_IFDIR as u32 | 0o555, - }, - ..Default::default() - } -} diff --git a/tvix/castore/src/fs/inodes.rs b/tvix/castore/src/fs/inodes.rs index 9131b703bae0..69a75acb6b0d 100644 --- a/tvix/castore/src/fs/inodes.rs +++ b/tvix/castore/src/fs/inodes.rs @@ -1,5 +1,7 @@ //! This module contains all the data structures used to track information //! about inodes, which present tvix-castore nodes in a filesystem. +use std::time::Duration; + use crate::proto as castorepb; use crate::B3Digest; @@ -10,6 +12,41 @@ pub enum InodeData { Directory(DirectoryInodeData), // either [DirectoryInodeData:Sparse] or [DirectoryInodeData:Populated] } +impl InodeData { + pub fn as_fuse_file_attr(&self, inode: u64) -> fuse_backend_rs::abi::fuse_abi::Attr { + fuse_backend_rs::abi::fuse_abi::Attr { + ino: inode, + // FUTUREWORK: play with this numbers, as it affects read sizes for client applications. + blocks: 1024, + size: match self { + InodeData::Regular(_, size, _) => *size, + InodeData::Symlink(target) => target.len() as u64, + InodeData::Directory(DirectoryInodeData::Sparse(_, size)) => *size, + InodeData::Directory(DirectoryInodeData::Populated(_, ref children)) => { + children.len() as u64 + } + }, + mode: match self { + InodeData::Regular(_, _, false) => libc::S_IFREG | 0o444, // no-executable files + InodeData::Regular(_, _, true) => libc::S_IFREG | 0o555, // executable files + InodeData::Symlink(_) => libc::S_IFLNK | 0o444, + InodeData::Directory(_) => libc::S_IFDIR | 0o555, + }, + ..Default::default() + } + } + + pub fn as_fuse_entry(&self, inode: u64) -> fuse_backend_rs::api::filesystem::Entry { + fuse_backend_rs::api::filesystem::Entry { + inode, + attr: self.as_fuse_file_attr(inode).into(), + attr_timeout: Duration::MAX, + entry_timeout: Duration::MAX, + ..Default::default() + } + } +} + /// This encodes the two different states of [InodeData::Directory]. /// Either the data still is sparse (we only saw a [castorepb::DirectoryNode], /// but didn't fetch the [castorepb::Directory] struct yet, or we processed a diff --git a/tvix/castore/src/fs/mod.rs b/tvix/castore/src/fs/mod.rs index 2bf22a33ff99..1988a49cfc15 100644 --- a/tvix/castore/src/fs/mod.rs +++ b/tvix/castore/src/fs/mod.rs @@ -14,7 +14,7 @@ mod tests; pub use self::root_nodes::RootNodes; use self::{ - file_attr::{gen_file_attr, ROOT_FILE_ATTR}, + file_attr::ROOT_FILE_ATTR, inode_tracker::InodeTracker, inodes::{DirectoryInodeData, InodeData}, }; @@ -328,9 +328,9 @@ where match self.inode_tracker.read().get(inode) { None => Err(io::Error::from_raw_os_error(libc::ENOENT)), - Some(node) => { - debug!(node = ?node, "found node"); - Ok((gen_file_attr(&node, inode).into(), Duration::MAX)) + Some(inode_data) => { + debug!(inode_data = ?inode_data, "found node"); + Ok((inode_data.as_fuse_file_attr(inode).into(), Duration::MAX)) } } } @@ -353,13 +353,7 @@ where let (ino, inode_data) = self.name_in_root_to_ino_and_data(name)?; debug!(inode_data=?&inode_data, ino=ino, "Some"); - return Ok(fuse_backend_rs::api::filesystem::Entry { - inode: ino, - attr: gen_file_attr(&inode_data, ino).into(), - attr_timeout: Duration::MAX, - entry_timeout: Duration::MAX, - ..Default::default() - }); + return Ok(inode_data.as_fuse_entry(ino)); } // This is the "lookup for "a" inside inode 42. // We already know that inode 42 must be a directory. @@ -376,13 +370,7 @@ where // Reply with the file attributes for the child. // For child directories, we still have all data we need to reply. - Ok(fuse_backend_rs::api::filesystem::Entry { - inode: *child_ino, - attr: gen_file_attr(&child_inode_data, *child_ino).into(), - attr_timeout: Duration::MAX, - entry_timeout: Duration::MAX, - ..Default::default() - }) + Ok(child_inode_data.as_fuse_entry(*child_ino)) } else { // Child not found, return ENOENT. Err(io::Error::from_raw_os_error(libc::ENOENT)) @@ -606,13 +594,7 @@ where type_: ty, name, }, - fuse_backend_rs::api::filesystem::Entry { - inode: ino, - attr: gen_file_attr(&inode_data, ino).into(), - attr_timeout: Duration::MAX, - entry_timeout: Duration::MAX, - ..Default::default() - }, + inode_data.as_fuse_entry(ino), )?; // If the buffer is full, add_entry will return `Ok(0)`. if written == 0 { @@ -646,13 +628,7 @@ where }, name: child_node.get_name(), }, - fuse_backend_rs::api::filesystem::Entry { - inode: *ino, - attr: gen_file_attr(&inode_data, *ino).into(), - attr_timeout: Duration::MAX, - entry_timeout: Duration::MAX, - ..Default::default() - }, + inode_data.as_fuse_entry(*ino), )?; // If the buffer is full, add_entry will return `Ok(0)`. if written == 0 { |