Skip to main content

mount/
error.rs

1// SPDX-License-Identifier: Apache-2.0
2//! Error types for the mount crate.
3//!
4//! Mount-side errors map cleanly to libc errno codes so the FUSE
5//! shell can hand them back to the kernel without a translation
6//! layer of its own. The mapping lives in [`MountError::to_errno`].
7
8use objects::error::HeddleError;
9
10/// Result alias used throughout the mount crate.
11pub type Result<T> = std::result::Result<T, MountError>;
12
13/// Errors surfaced by the content-addressed mount core.
14#[derive(Debug, thiserror::Error)]
15pub enum MountError {
16    /// The requested path or node does not exist in the current state.
17    #[error("not found: {0}")]
18    NotFound(String),
19
20    /// The node referenced by the caller is no longer valid (stale
21    /// inode, invalidated cache, etc).
22    #[error("stale node: {0}")]
23    Stale(String),
24
25    /// A path component traversed something that wasn't a directory.
26    #[error("not a directory: {0}")]
27    NotADirectory(String),
28
29    /// The thread name does not resolve to a current state.
30    #[error("thread {0} has no current state")]
31    UnknownThread(String),
32
33    /// Read-only filesystem (used while overlay-write is stubbed).
34    #[error("read-only filesystem")]
35    ReadOnly,
36
37    /// Errors bubbling up from the underlying object store / repo.
38    #[error(transparent)]
39    Store(#[from] HeddleError),
40}
41
42impl MountError {
43    /// Translate this error into a libc errno suitable for handing
44    /// back to FUSE. Only the platform shell uses this — keeping it
45    /// here means platform code stays one-liners.
46    pub fn to_errno(&self) -> i32 {
47        match self {
48            MountError::NotFound(_) | MountError::UnknownThread(_) => libc::ENOENT,
49            MountError::Stale(_) => libc::ESTALE,
50            MountError::NotADirectory(_) => libc::ENOTDIR,
51            MountError::ReadOnly => libc::EROFS,
52            MountError::Store(HeddleError::NotFound(_))
53            | MountError::Store(HeddleError::StateNotFound(_))
54            | MountError::Store(HeddleError::MissingObject { .. }) => libc::ENOENT,
55            MountError::Store(HeddleError::Io(io)) => io.raw_os_error().unwrap_or(libc::EIO),
56            MountError::Store(_) => libc::EIO,
57        }
58    }
59}