pub trait PlatformShell {
// Required methods
fn lookup(&self, parent: NodeId, name: &OsStr) -> Result<Option<Entry>>;
fn read(&self, node: NodeId, offset: u64, buf: &mut [u8]) -> Result<usize>;
fn write(&self, node: NodeId, offset: u64, data: &[u8]) -> Result<usize>;
fn enumerate(&self, dir: NodeId) -> Result<Vec<Entry>>;
fn attrs(&self, node: NodeId) -> Result<Attrs>;
fn invalidate(&self, node: NodeId) -> Result<()>;
// Provided methods
fn flush(&self, _node: NodeId) -> Result<()> { ... }
fn release(&self, node: NodeId) -> Result<()> { ... }
}Expand description
Platform-agnostic operations every adapter implements against a shared core. Names mirror the eventual FUSE callbacks (and the equivalent FSKit / ProjFS hooks) so the platform layer can be almost trivial.
§Write lifecycle
Mount writes flow through three calls:
write— kernel issues a sequence ofwrite(offset, bytes)calls against an open file. The core accumulates these in an in-memory hot-tier buffer keyed byNodeId.flush— kernel signals the buffer can be made durable (mapped to FUSE’sflushcallback, which fires onclose(2)and on explicit fsync). The core promotes the hot buffer to a CAS blob and recordspath -> blob_oidin the per-thread pending tree. Buffer is dropped.release— kernel signals the file is closed and the inode handle can be retired. The default contract: identical to flush. FUSE doesn’t always issueflushcleanly on every close path, so adapters should callreleasehere too as a belt-and-braces measure.
Implementations MAY also promote a hot buffer opportunistically (e.g. after an idle window) — this is a safety net for files that the kernel never explicitly closes.
Required Methods§
Sourcefn lookup(&self, parent: NodeId, name: &OsStr) -> Result<Option<Entry>>
fn lookup(&self, parent: NodeId, name: &OsStr) -> Result<Option<Entry>>
Look up name inside parent. Returns None for ENOENT.
Sourcefn read(&self, node: NodeId, offset: u64, buf: &mut [u8]) -> Result<usize>
fn read(&self, node: NodeId, offset: u64, buf: &mut [u8]) -> Result<usize>
Read up to buf.len() bytes from node, starting at offset.
Returns the number of bytes actually written into buf.
Sourcefn write(&self, node: NodeId, offset: u64, data: &[u8]) -> Result<usize>
fn write(&self, node: NodeId, offset: u64, data: &[u8]) -> Result<usize>
Write data to node at offset. Returns bytes written.
Sourcefn invalidate(&self, node: NodeId) -> Result<()>
fn invalidate(&self, node: NodeId) -> Result<()>
Drop any cached identity for node. The platform layer calls
this when the underlying state moves and previously-handed-out
inode numbers may now point at the wrong content.