Skip to main content

PlatformShell

Trait PlatformShell 

Source
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:

  1. write — kernel issues a sequence of write(offset, bytes) calls against an open file. The core accumulates these in an in-memory hot-tier buffer keyed by NodeId.
  2. flush — kernel signals the buffer can be made durable (mapped to FUSE’s flush callback, which fires on close(2) and on explicit fsync). The core promotes the hot buffer to a CAS blob and records path -> blob_oid in the per-thread pending tree. Buffer is dropped.
  3. release — kernel signals the file is closed and the inode handle can be retired. The default contract: identical to flush. FUSE doesn’t always issue flush cleanly on every close path, so adapters should call release here 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§

Source

fn lookup(&self, parent: NodeId, name: &OsStr) -> Result<Option<Entry>>

Look up name inside parent. Returns None for ENOENT.

Source

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.

Source

fn write(&self, node: NodeId, offset: u64, data: &[u8]) -> Result<usize>

Write data to node at offset. Returns bytes written.

Source

fn enumerate(&self, dir: NodeId) -> Result<Vec<Entry>>

List the children of dir.

Source

fn attrs(&self, node: NodeId) -> Result<Attrs>

Stat node.

Source

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.

Provided Methods§

Source

fn flush(&self, _node: NodeId) -> Result<()>

Promote any hot-tier buffer for node into a CAS blob. The FUSE flush callback dispatches here (fires on close(2) and explicit fsync). Default: no-op for read-only mounts.

Source

fn release(&self, node: NodeId) -> Result<()>

Final close of node. Adapters call this on FUSE release so a buffer that survived a missed flush still gets promoted before the inode handle is retired. Default: identical to flush.

Implementors§