Skip to content
Xila
Demonstration

File system

The file_system crate is the architectural contract layer for storage nodes, files, directories, and device endpoints.

Last updatedEdit page

The file_system crate is the architectural contract layer for storage nodes, files, directories, and device endpoints.

  • Defines fundamental types (Path, flags, permissions, metadata, errors, identifiers).
  • Defines operation traits consumed by VFS and implemented by concrete backends/devices, including optional symbolic-link operations.
  • Provides reusable helpers for memory devices, partitions, and MBR handling.
  • In scope: trait contracts and shared semantics for file/device operations.
  • Out of scope: global namespace mounting/orchestration (handled by Virtual file system).
  • fundamentals/: path, identifiers, permissions, statistics, flags, entry/type primitives.
  • operations/: core trait families (FileSystemOperations, BaseOperations, DirectoryOperations, …).
  • devices/: character/block device abstractions and direct operations.
  • mbr/: partition tables and partition helpers; devices/partition_device.rs implements partition-device access.
  • devices/memory_device.rs: in-memory block device implementation.
  • VFS calls file-system and device traits through dynamic dispatch.
  • Device nodes expose control commands and read/write operations via the same contract surface.
  • Backends like Little FS map these traits to concrete storage engines.
  • Uniform file_system::Error result model across traits.
  • Unsupported operations are explicit (UnsupportedOperation), allowing capability probing by callers.
  • Backend-specific failures are expected to be translated into this crate’s error domain.
  • Add new backend crates by implementing the operation traits.
  • Extend control-command families while preserving command identifiers for compatibility.
  • Add helper devices/partition utilities without changing core trait contracts.
  • Contract: typed trait and data-model surface for file and device operations.
  • Current implementation: includes reusable helpers (MemoryDevice, MBR/partition utilities) but delegates namespace-level behavior to VFS.
  • Intentionally broad contract surface increases flexibility, but requires careful implementer conformance.
  • Policy decisions (mount precedence, path traversal context, async scheduling) live outside this crate.

FileSystemOperations extends FileOperations, DirectoryOperations and MountOperations; a concrete backend implements path lookup/create/remove/rename and attribute access without assuming a global namespace. The VFS owns mounts, caller identity, path routing and authorization; a standalone FileSystemOperations backend does not.

The device side supports both contextual BaseOperations (per-open Context) and direct devices, plus typed control commands. BaseOperations::read, write, flush and control return Poll<file_system::Result<T>>:

  • Poll::Pending means the backend has registered a race-free waker and will signal readiness. It must not retain pointers to the caller’s buffers or task context.
  • Poll::Ready(Err(Error::RessourceBusy)) is an immediate busy failure, not a request for the caller to spin.
  • Synchronous *_sync adapters make a single attempt; if the operation would be pending they cancel the registration and return a busy error.
  • Short reads/writes are permitted. Callers must not assume a successful result consumes the entire buffer.

The ready(|| ...) helper wraps a synchronous operation into Poll::Ready exactly once, without a hidden retry loop.

FileSystemOperations exposes create_symlink(target, link) and read_symlink(link, buffer); their default implementations return UnsupportedOperation. A backend can implement native links, or the VFS can store a target path in the file payload and label the entry with persistent Kind::SymbolicLink metadata where that capability exists. The VFS, not this library, resolves links and enforces caller permissions. Link support therefore depends on backend capabilities, not merely on the existence of the trait methods.

FileSystemOperations::writable_attributes() reports which AttributeFlags can be stored by the backend. get_attributes only sets requested fields it can actually supply, and must not invent data to satisfy a mask. set_attributes must reject unsupported requested attributes before modifying supported fields. A later I/O failure may still leave earlier supported attributes changed: it does not guarantee transactional rollback.

Path is a lightweight borrowed, no_std path type, while PathOwned owns its string. Permission flags, user/group identifiers, timestamp attributes and item statistics are shared across backends; they should not be reinterpreted in a driver-specific ABI.

A new backend should validate path operations; propagate UnsupportedOperation rather than silently succeeding; maintain per-open Context state; support appropriate Poll/Waker cancellation; implement consistent attribute masks; and document geometry, concurrency and unmount constraints. The generic file-system tests in operations/file_system.rs can exercise CRUD, rename, directory iteration, positioned I/O, attributes and invalid-path handling.

use file_system::{Path, PathOwned};
let root = Path::from_str("/data");
let item: PathOwned = root.join(Path::from_str("config.json")).unwrap();
assert_eq!(item.as_str(), "/data/config.json");