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}