fs: Support for symlinks
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 2.7k
- Forks
- 144
- Avg merge
- 12h 21m
- Merged PRs (30d)
- 146
Description
We should add support for symlinks. This is somewhat complicated by the fact that we'd also need to support it at the layered FS, which means that cross-layer symlinks are possible (for example, /proc/self/fd/0 should be an upper-layer FS symlink to the lower-level /dev/stdin devices FS).
I think a simplification to think about this is to only allow top-to-bottom symlinks, and disallow bottom-to-top ones. When trying to handle both-direction symlinks, things get quite complicated. Handling only in one direction I think leads to a simpler design, but I haven't yet finished sketching the design out just yet.
The interface to be added looks a bit like this:
Click to expand
diff --git a/litebox/src/fs/mod.rs b/litebox/src/fs/mod.rs
index 53aefea575..e55e2e47ca 100644
--- a/litebox/src/fs/mod.rs
+++ b/litebox/src/fs/mod.rs
@@ -21,7 +21,8 @@
use errors::{
ChmodError, ChownError, CloseError, FileStatusError, MkdirError, OpenError, ReadDirError,
- ReadError, RmdirError, SeekError, TruncateError, UnlinkError, WriteError,
+ ReadError, ReadLinkError, RmdirError, SeekError, SymlinkError, TruncateError, UnlinkError,
+ WriteError,
};
/// A private module, to help support writing sealed traits. This module should _itself_ never be
@@ -127,10 +128,31 @@
fn read_dir(&self, fd: &TypedFd<Self>) -> Result<Vec<DirEntry>, ReadDirError>;
/// Obtain the status of a file/directory/... on the file-system.
- fn file_status(&self, path: impl path::Arg) -> Result<FileStatus, FileStatusError>;
+ ///
+ /// If `follow_last_symlink` is true, symlinks are followed (like `stat()`).
+ /// If false, symlinks are not followed (like `lstat()`).
+ fn file_status(
+ &self,
+ path: impl path::Arg,
+ follow_last_symlink: bool,
+ ) -> Result<FileStatus, FileStatusError>;
/// Equivalent to [`Self::file_status`], but open an open `fd` instead.
fn fd_file_status(&self, fd: &TypedFd<Self>) -> Result<FileStatus, FileStatusError>;
+
+ /// Create a symbolic link pointing from `link_path` to `target`.
+ ///
+ /// The `target` does not need to exist at the time the symlink is created.
+ fn symlink(
+ &self,
+ target: impl path::Arg,
+ link_path: impl path::Arg,
+ ) -> Result<(), SymlinkError>;
+
+ /// Read the target of a symbolic link.
+ ///
+ /// This operation does not follow the symlink, but reads the stored target path.
+ fn read_link(&self, path: impl path::Arg) -> Result<alloc::string::String, ReadLinkError>;
}
bitflags! {
@@ -182,6 +204,7 @@
RegularFile,
Directory,
CharacterDevice,
+ SymbolicLink,
}
bitflags! {
Note: when we add this implementation, we should make sure we've looked over #384
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in litebox/src/fs/mod.rs, reviewing the proposed file-status, symlink, read-link, and SymbolicLink interfaces, then examine the layered filesystem design and issue #384. Done means symlink creation and target reading are supported across the layered filesystem under an agreed top-to-bottom policy, with file-status behavior matching the stated stat/lstat distinction.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- operating-systems
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100