sausage-vfs: review fixes (fallible growth, symlink flags, stream cancel, sized reads, timestamps, error kinds, linker shadowing)

API: Layer::stat(path, follow), Layer::readlink, Open::follow,
Stat::symlink and Entry::symlink. Process::idle documents the shutdown
order: abort, await the task, await idle, release locks.
This commit is contained in:
2026-10-23 00:49:46 +01:00
parent 7bbcd47837
commit 151550242b
14 changed files with 673 additions and 97 deletions
+10 -3
View File
@@ -2,7 +2,8 @@
use crate::*;
use std::{collections::BTreeMap, io::ErrorKind as E};
type Generator = Arc<dyn Fn() -> Result<Vec<u8>> + Send + Sync>;
/// A tree of generated files. Parent folders are implicit.
/// A static tree of generated files. Parent folders are implicit.
/// Generators must be cheap and must not block. Stat can invoke them as well as open.
#[derive(Default)]
pub struct Generated {
files: BTreeMap<String, Generator>,
@@ -29,7 +30,7 @@ fn readonly<T>() -> Result<T> {
}
#[async_trait]
impl Layer for Generated {
async fn stat(&self, path: &str) -> Result<Stat> {
async fn stat(&self, path: &str, _follow: bool) -> Result<Stat> {
if let Some(f) = self.files.get(path) {
return Snapshot(f()?).stat().await;
}
@@ -38,6 +39,7 @@ impl Layer for Generated {
}
Ok(Stat {
directory: true,
symlink: false,
size: 0,
accessed: None,
modified: None,
@@ -67,7 +69,11 @@ impl Layer for Generated {
}
Ok(entries
.into_iter()
.map(|(name, directory)| Entry { name, directory })
.map(|(name, directory)| Entry {
name,
directory,
symlink: false,
})
.collect())
}
async fn open(&self, path: &str, o: Open) -> Result<Arc<dyn File>> {
@@ -103,6 +109,7 @@ impl File for Snapshot {
async fn stat(&self) -> Result<Stat> {
Ok(Stat {
directory: false,
symlink: false,
size: self.0.len() as u64,
accessed: None,
modified: None,