about summary refs log tree commit diff
path: root/tvix/castore/src/fs/inodes.rs
diff options
context:
space:
mode:
authorFlorian Klink <flokli@flokli.de>2024-04-15T12·14+0300
committerclbot <clbot@tvl.fyi>2024-04-15T14·49+0000
commitb025a30d271458386769e8721231e1e219481f57 (patch)
tree527e18db09312e6779d6c8bf4828f42a08ec0be1 /tvix/castore/src/fs/inodes.rs
parentfb852b0245aab7637ffca2b7583be2e282cfe063 (diff)
refactor(tvix/castore/fs): remove From<Node> for InodeData r/7931
These were copying unnecessarily. Instead, have a
InodeData::from_node(), which *consumes* the Node entirely, returns
`InodeData` and the split-off name (which is not part of InodeData).

Callers can then use the result in various helper functions, like:

 - InodeData::as_fuse_type
 - InodeData::as_fuse_file_attr
 - InodeData::as_fuse_entry

… to prepare their replies to the kernel.

This removes not only a bunch of clones, but also a lot of copy-pasted
code.

Change-Id: Idbca5f25cc29e96c1f4c614b33dff2becb0a8738
Reviewed-on: https://cl.tvl.fyi/c/depot/+/11435
Tested-by: BuildkiteCI
Autosubmit: flokli <flokli@flokli.de>
Reviewed-by: Connor Brewster <cbrewster@hey.com>
Diffstat (limited to 'tvix/castore/src/fs/inodes.rs')
-rw-r--r--tvix/castore/src/fs/inodes.rs86
1 files changed, 43 insertions, 43 deletions
diff --git a/tvix/castore/src/fs/inodes.rs b/tvix/castore/src/fs/inodes.rs
index 69a75acb6b0d..c22bd4b2ebdc 100644
--- a/tvix/castore/src/fs/inodes.rs
+++ b/tvix/castore/src/fs/inodes.rs
@@ -2,6 +2,8 @@
 //! about inodes, which present tvix-castore nodes in a filesystem.
 use std::time::Duration;
 
+use bytes::Bytes;
+
 use crate::proto as castorepb;
 use crate::B3Digest;
 
@@ -12,7 +14,36 @@ pub enum InodeData {
     Directory(DirectoryInodeData), // either [DirectoryInodeData:Sparse] or [DirectoryInodeData:Populated]
 }
 
+/// 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
+/// lookup and did fetch the data.
+#[derive(Clone, Debug)]
+pub enum DirectoryInodeData {
+    Sparse(B3Digest, u64),                                  // digest, size
+    Populated(B3Digest, Vec<(u64, castorepb::node::Node)>), // [(child_inode, node)]
+}
+
 impl InodeData {
+    /// Constructs a new InodeData by consuming a [Node].
+    /// It splits off the orginal name, so it can be used later.
+    pub fn from_node(node: castorepb::node::Node) -> (Self, Bytes) {
+        match node {
+            castorepb::node::Node::Directory(n) => (
+                Self::Directory(DirectoryInodeData::Sparse(
+                    n.digest.try_into().unwrap(),
+                    n.size,
+                )),
+                n.name,
+            ),
+            castorepb::node::Node::File(n) => (
+                Self::Regular(n.digest.try_into().unwrap(), n.size, n.executable),
+                n.name,
+            ),
+            castorepb::node::Node::Symlink(n) => (Self::Symlink(n.target), n.name),
+        }
+    }
+
     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,
@@ -45,50 +76,19 @@ impl InodeData {
             ..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
-/// lookup and did fetch the data.
-#[derive(Clone, Debug)]
-pub enum DirectoryInodeData {
-    Sparse(B3Digest, u64),                                  // digest, size
-    Populated(B3Digest, Vec<(u64, castorepb::node::Node)>), // [(child_inode, node)]
-}
-
-impl From<&castorepb::node::Node> for InodeData {
-    fn from(value: &castorepb::node::Node) -> Self {
-        match value {
-            castorepb::node::Node::Directory(directory_node) => directory_node.into(),
-            castorepb::node::Node::File(file_node) => file_node.into(),
-            castorepb::node::Node::Symlink(symlink_node) => symlink_node.into(),
-        }
-    }
-}
-
-impl From<&castorepb::SymlinkNode> for InodeData {
-    fn from(value: &castorepb::SymlinkNode) -> Self {
-        InodeData::Symlink(value.target.clone())
-    }
-}
 
-impl From<&castorepb::FileNode> for InodeData {
-    fn from(value: &castorepb::FileNode) -> Self {
-        InodeData::Regular(
-            value.digest.clone().try_into().unwrap(),
-            value.size,
-            value.executable,
-        )
-    }
-}
+    /// Returns the u32 fuse type
+    pub fn as_fuse_type(&self) -> u32 {
+        #[allow(clippy::let_and_return)]
+        let ty = match self {
+            InodeData::Regular(_, _, _) => libc::S_IFREG,
+            InodeData::Symlink(_) => libc::S_IFLNK,
+            InodeData::Directory(_) => libc::S_IFDIR,
+        };
+        // libc::S_IFDIR is u32 on Linux and u16 on MacOS
+        #[cfg(target_os = "macos")]
+        let ty = ty as u32;
 
-/// Converts a DirectoryNode to a sparsely populated InodeData::Directory.
-impl From<&castorepb::DirectoryNode> for InodeData {
-    fn from(value: &castorepb::DirectoryNode) -> Self {
-        InodeData::Directory(DirectoryInodeData::Sparse(
-            value.digest.clone().try_into().unwrap(),
-            value.size,
-        ))
+        ty
     }
 }