Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 90 additions & 1 deletion litebox/src/fs/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,23 @@ pub enum OpenError {
TruncateError(#[from] TruncateError),
#[error("I/O error")]
Io,
#[error("operation interrupted")]
Interrupted,
#[error("fd has been closed already")]
ClosedFd,
#[error("a component used as a directory in pathname is not, in fact, a directory")]
NotADirectory,
#[error(transparent)]
PathError(#[from] PathError),
}

/// Possible errors from [`FileSystem::close`]
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum CloseError {}
pub enum CloseError {
#[error("I/O error")]
Io,
}

/// Possible errors from [`FileSystem::read`]
#[non_exhaustive]
Expand All @@ -48,6 +57,10 @@ pub enum ReadError {
NotForReading,
#[error("I/O error")]
Io,
#[error("read would block")]
WouldBlock,
#[error("operation interrupted")]
Interrupted,
}

/// Possible errors from [`FileSystem::write`]
Expand All @@ -62,6 +75,8 @@ pub enum WriteError {
NotForWriting,
#[error("I/O error")]
Io,
#[error("operation interrupted")]
Interrupted,
}

/// Possible errors from [`FileSystem::seek`]
Expand Down Expand Up @@ -141,6 +156,10 @@ pub enum UnlinkError {
ReadOnlyFileSystem,
#[error("I/O error")]
Io,
#[error("fd has been closed already")]
ClosedFd,
#[error("a component used as a directory in pathname is not, in fact, a directory")]
NotADirectory,
#[error(transparent)]
PathError(#[from] PathError),
}
Expand Down Expand Up @@ -203,6 +222,10 @@ pub enum FileStatusError {
ClosedFd,
#[error("I/O error")]
Io,
#[error("a component used as a directory in pathname is not, in fact, a directory")]
NotADirectory,
#[error("too many levels of symbolic links")]
SymlinkLoop,
#[error(transparent)]
PathError(#[from] PathError),
}
Expand Down Expand Up @@ -232,3 +255,69 @@ impl From<crate::path::ConversionError> for PathError {
Self::InvalidPathname
}
}

/// Possible errors from [`FileSystem::create_anonymous_file`]
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum CreateAnonymousFileError {
#[error("the filesystem does not support anonymous files")]
NotSupported,
#[error("I/O error")]
Io,
}

/// Possible errors from [`FileSystem::rename`]
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum RenameError {
#[error("the parent directory does not allow write permission")]
NoWritePerms,
#[error("the named file resides on a read-only filesystem")]
ReadOnlyFileSystem,
#[error("I/O error")]
Io,
#[error("operation not supported")]
NotSupported,
#[error(transparent)]
PathError(#[from] PathError),
}

/// Possible errors from [`FileSystem::read_link`]
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum ReadLinkError {
#[error("the filesystem does not support symlinks")]
NotSupported,
#[error("I/O error")]
Io,
#[error(transparent)]
PathError(#[from] PathError),
}

/// Possible errors from [`FileSystem::symlink`]
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum SymlinkError {
#[error("the filesystem does not support symlinks")]
NotSupported,
#[error("path already exists")]
AlreadyExists,
#[error("I/O error")]
Io,
#[error(transparent)]
PathError(#[from] PathError),
}

/// Possible errors from [`FileSystem::link`]
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum LinkError {
#[error("the filesystem does not support hard links")]
NotSupported,
#[error("path already exists")]
AlreadyExists,
#[error("I/O error")]
Io,
#[error(transparent)]
PathError(#[from] PathError),
}
37 changes: 32 additions & 5 deletions litebox/src/fs/layered.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,17 @@ impl<Platform: sync::RawSyncPrimitivesProvider, Upper: super::FileSystem, Lower:
},
}
}
Ok(FileType::RegularFile | FileType::CharacterDevice)
Ok(FileType::RegularFile | FileType::CharacterDevice | FileType::Symlink)
| Err(
FileStatusError::PathError(PathError::MissingComponent)
| FileStatusError::ClosedFd,
) => unreachable!(),
Err(FileStatusError::NotADirectory) => {
unimplemented!()
}
Err(FileStatusError::SymlinkLoop) => {
unimplemented!()
}
Err(FileStatusError::PathError(PathError::ComponentNotADirectory)) => {
unimplemented!()
}
Expand Down Expand Up @@ -208,6 +214,9 @@ impl<Platform: sync::RawSyncPrimitivesProvider, Upper: super::FileSystem, Lower:
OpenError::NoWritePerms
| OpenError::ReadOnlyFileSystem
| OpenError::AlreadyExists
| OpenError::Interrupted
| OpenError::ClosedFd
| OpenError::NotADirectory
| OpenError::TruncateError(_) => unreachable!(),
OpenError::PathError(path_error) => return Err(path_error)?,
},
Expand Down Expand Up @@ -260,7 +269,10 @@ impl<Platform: sync::RawSyncPrimitivesProvider, Upper: super::FileSystem, Lower:
// In which case we quit early
return Err(MigrationError::NotAFile);
}
ReadError::ClosedFd | ReadError::NotForReading => unreachable!(),
ReadError::ClosedFd
| ReadError::NotForReading
| ReadError::WouldBlock
| ReadError::Interrupted => unreachable!(),
ReadError::Io => return Err(MigrationError::Io),
},
}
Expand Down Expand Up @@ -538,6 +550,9 @@ impl<
| OpenError::NoWritePerms
| OpenError::ReadOnlyFileSystem
| OpenError::AlreadyExists
| OpenError::Interrupted
| OpenError::ClosedFd
| OpenError::NotADirectory
| OpenError::TruncateError(
TruncateError::IsDirectory
| TruncateError::NotForWriting
Expand Down Expand Up @@ -958,6 +973,8 @@ impl<
Err(FileStatusError::Io) => return Err(ChmodError::Io),
Err(FileStatusError::PathError(e)) => return Err(ChmodError::PathError(e)),
Err(FileStatusError::ClosedFd) => unreachable!(),
Err(FileStatusError::NotADirectory) => unimplemented!(),
Err(FileStatusError::SymlinkLoop) => unimplemented!(),
}
match self.migrate_file_up(&path, true) {
Ok(()) => {}
Expand Down Expand Up @@ -1003,6 +1020,8 @@ impl<
Err(FileStatusError::Io) => return Err(ChownError::Io),
Err(FileStatusError::PathError(e)) => return Err(ChownError::PathError(e)),
Err(FileStatusError::ClosedFd) => unreachable!(),
Err(FileStatusError::NotADirectory) => unimplemented!(),
Err(FileStatusError::SymlinkLoop) => unimplemented!(),
}
match self.migrate_file_up(&path, true) {
Ok(()) => {}
Expand Down Expand Up @@ -1035,6 +1054,8 @@ impl<
| UnlinkError::Io
| UnlinkError::IsADirectory
| UnlinkError::ReadOnlyFileSystem
| UnlinkError::ClosedFd
| UnlinkError::NotADirectory
| UnlinkError::PathError(
PathError::ComponentNotADirectory
| PathError::InvalidPathname
Expand All @@ -1048,17 +1069,18 @@ impl<
// We must now check if the lower level contains the file; if it does not, we
// must exit with failure. Otherwise, we fallthrough to place the tombstone.
match self.ensure_lower_contains(&path).map_err(|e| match e {
FileStatusError::Io => UnlinkError::Io,
FileStatusError::Io | FileStatusError::SymlinkLoop => UnlinkError::Io,
FileStatusError::PathError(p) => UnlinkError::PathError(p),
FileStatusError::ClosedFd => unreachable!(),
FileStatusError::NotADirectory => UnlinkError::NotADirectory,
})? {
FileType::RegularFile => {
// fallthrough
}
FileType::Directory => {
return Err(UnlinkError::IsADirectory);
}
FileType::CharacterDevice => unimplemented!(),
FileType::CharacterDevice | FileType::Symlink => unimplemented!(),
}
}
},
Expand Down Expand Up @@ -1138,6 +1160,9 @@ impl<
}
OpenError::NoWritePerms
| OpenError::AlreadyExists
| OpenError::Interrupted
| OpenError::ClosedFd
| OpenError::NotADirectory
| OpenError::TruncateError(_) => {
unreachable!()
}
Expand Down Expand Up @@ -1315,7 +1340,9 @@ impl<
// None of these can be handled by lower level, just quit out early
return Err(e);
}
FileStatusError::Io => return Err(e),
FileStatusError::Io
| FileStatusError::NotADirectory
| FileStatusError::SymlinkLoop => return Err(e),
FileStatusError::PathError(
PathError::NoSuchFileOrDirectory | PathError::MissingComponent,
) => {
Expand Down
Loading
Loading