Skip to content
Open
7 changes: 7 additions & 0 deletions litebox/src/fs/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ pub enum WriteError {
/// Copying from the buffer faulted before anything was written.
#[error("copying from the buffer faulted")]
Fault,
/// The storage holding the file's contents cannot grow to hold the write.
#[error("no space is left for the file's contents")]
NoSpace,
}

/// Possible errors from [`super::File::seek`].
Expand Down Expand Up @@ -109,6 +112,10 @@ pub enum TruncateError {
NotOpenForWriting,
#[error("file descriptor points to a terminal device")]
IsTerminalDevice,
#[error("the file cannot shrink while it is mapped")]
Busy,
#[error("no space is left for the file's contents")]
NoSpace,
#[error("I/O error")]
Io,
}
Expand Down
4 changes: 4 additions & 0 deletions litebox/src/fs/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,7 @@ impl From<FileError> for OpenError {
FileError::IsDirectory => Self::TruncateError(TruncateError::IsDirectory),
FileError::NotForWriting => Self::TruncateError(TruncateError::NotForWriting),
FileError::IsTerminalDevice => Self::TruncateError(TruncateError::IsTerminalDevice),
FileError::Busy => Self::TruncateError(TruncateError::Busy),
FileError::NoSuchDevice => Self::NoSuchDevice,
FileError::NoSpace => Self::NoSpace,
_ => Self::Io,
Expand All @@ -772,6 +773,7 @@ impl From<FileError> for WriteError {
match error {
FileError::NotFile => Self::NotAFile,
FileError::AccessNotAllowed | FileError::NotForWriting => Self::NotForWriting,
FileError::NoSpace => Self::NoSpace,
_ => Self::Io,
}
}
Expand All @@ -797,6 +799,8 @@ impl From<FileError> for TruncateError {
FileError::AccessNotAllowed | FileError::NotForWriting => Self::NotForWriting,
FileError::PathOnly => Self::NotOpenForWriting,
FileError::IsTerminalDevice => Self::IsTerminalDevice,
FileError::Busy => Self::Busy,
FileError::NoSpace => Self::NoSpace,
_ => Self::Io,
}
}
Expand Down
19 changes: 16 additions & 3 deletions litebox_broker_core/src/fs/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ use core::marker::PhantomData;
use litebox_platform::buffer::{ReadBuffer, WriteBuffer};

use super::errors::{
ChmodError, ChownError, FileStatusError, MkdirError, OpenError, ReadDirError, ReadError,
RenameError, ResolutionError, RmdirError, SymlinkError, TruncateError, UnlinkError, WalkError,
WriteError,
ChmodError, ChownError, FileStatusError, MapSharedError, MkdirError, OpenError, ReadDirError,
ReadError, RenameError, ResolutionError, RmdirError, SymlinkError, TruncateError, UnlinkError,
WalkError, WriteError,
};
use super::shared_memory::SharedFile;
use super::{DirEntry, FileStatus, FileType, Mode, OFlags, UserInfo};
use crate::readiness::ReadinessSource;
use crate::terminal::TerminalEndpoint;
Expand Down Expand Up @@ -145,6 +146,18 @@ pub trait Backend: Send + Sync + Any {
None
}

/// Returns the host shared object that holds the file's contents.
///
/// After this succeeds, the backend must keep the file's contents in that object, so that
/// every mapping and every read, write, and truncation see the same bytes, and must return
/// the same object for every later call on the same file.
///
/// The default implementation returns [`MapSharedError::Unsupported`].
#[expect(unused_variables, reason = "default body with unused parameter")]
fn map_shared(&self, h: &FileHandle) -> Result<Arc<SharedFile>, MapSharedError> {
Err(MapSharedError::Unsupported)
}

/// Write `buf` into the file, based on `offset` (see [`crate::transfer`]), returning the number
/// of bytes written from its start.
///
Expand Down
12 changes: 9 additions & 3 deletions litebox_broker_core/src/fs/composer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ use super::backend::{
PermissionInfo, Resolution, ResolvedDir, ResolvedFile, ResolvedTarget, SeekBehavior,
};
use super::errors::{
ChmodError, ChownError, FileStatusError, MkdirError, OpenError, PathError, ReadDirError,
ReadError, RenameError, ResolutionError, RmdirError, SymlinkError, TruncateError, UnlinkError,
WalkError, WriteError,
ChmodError, ChownError, FileStatusError, MapSharedError, MkdirError, OpenError, PathError,
ReadDirError, ReadError, RenameError, ResolutionError, RmdirError, SymlinkError, TruncateError,
UnlinkError, WalkError, WriteError,
};
use super::inode_allocator::{InodeAllocator, InodeAllocators};
use super::shared_memory::SharedFile;
use super::{DirEntry, FileStatus, FileType, Mode, NodeInfo, OFlags, UserInfo};
use crate::readiness::ReadinessSource;
use thiserror::Error;
Expand Down Expand Up @@ -735,6 +736,11 @@ impl Backend for Composer {
.get_static_backing_data(&h.handle)
}

fn map_shared(&self, h: &FileHandle) -> Result<Arc<SharedFile>, MapSharedError> {
let h = h.get_typed::<Self>();
self.mounts[h.mount_index].backend.map_shared(&h.handle)
}

fn write(
&self,
h: &FileHandle,
Expand Down
25 changes: 25 additions & 0 deletions litebox_broker_core/src/fs/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ pub enum WriteError {
Io,
#[error("no space is available yet")]
WouldBlock,
/// The storage holding the file's contents cannot grow to hold the write.
#[error("no space is left for the file's contents")]
NoSpace,
/// The broker failed the write itself, such as when copying from the
/// caller's buffer faulted or it ran out of memory.
#[error(transparent)]
Expand Down Expand Up @@ -114,6 +117,28 @@ pub enum TruncateError {
NotOpenForWriting,
#[error("file descriptor points to a terminal device")]
IsTerminalDevice,
#[error("the file cannot shrink while it is mapped")]
Busy,
#[error("no space is left for the file's contents")]
NoSpace,
#[error("I/O error")]
Io,
}

/// Possible errors from [`super::resolver::Resolver::map_shared`] and
/// [`super::backend::Backend::map_shared`]
#[derive(Error, Debug)]
pub enum MapSharedError {
#[error("file descriptor points to a directory")]
IsDirectory,
#[error("file is not opened for reading")]
NotForReading,
#[error("file descriptor is not open for reading or writing")]
PathOnly,
#[error("the file system cannot share this file's pages")]
Unsupported,
#[error("out of host shared memory")]
NoMemory,
#[error("I/O error")]
Io,
}
Expand Down
Loading
Loading