Skip to content
Xila
Demonstration

Little FS

The little_fs crate is the concrete LittleFS backend that implements Xila's file-system contracts.

Last updatedEdit page

The little_fs crate is the concrete LittleFS backend that implements Xila’s file-system contracts.

  • Implements file_system::FileSystemOperations and related traits on top of littlefs2-sys.
  • Provides mount/format bootstrap paths used before VFS initialization.
  • In scope: backend adaptation, attribute translation, file/directory context operations.
  • Out of scope: global mount namespace and path policy (owned by VFS).
  • file_system.rs: FileSystem type, mount/format lifecycle, trait implementations.
  • callbacks.rs + configuration.rs: glue from DirectBlockDevice to LittleFS C callbacks/config.
  • file.rs / directory.rs: context-specific file and directory operations.
  • attributes.rs / flags.rs: mapping between Xila and LittleFS representations.
  • error.rs: LittleFS result-to-file_system::Error conversion.
  1. Backend is created via FileSystem::new(...), new_format(...), or get_or_format(...).
  2. It mounts using littlefs::lfs_mount and seeds root internal attributes if missing.
  3. VFS calls trait methods; crate routes calls through a mounted mutex wrapper.
  4. On drop, it unmounts and releases leaked configuration context.
  • Mount/format/operation failures are translated to file_system::Error.
  • get_or_format retries by formatting when initial mount fails.
  • Context type mismatch in operation dispatch returns InvalidParameter.
  • Additional mount policies can wrap existing constructors.
  • New attribute/flag translations can be added without changing trait-level contracts.
  • Contract: fully conforms to file_system trait interfaces expected by VFS.
  • Current implementation: based on LittleFS C runtime (lfs_*) with MutexMountWrapper<CriticalSectionRawMutex, lfs_t>.
  • Behavior inherits LittleFS semantics and target storage constraints.
  • Relies on callback/config correctness; misconfigured block geometry can fail at runtime.

The public constructors have distinct data-loss implications:

  • FileSystem::new(device, cache_size) mounts an existing filesystem and reports errors if it cannot mount.
  • FileSystem::new_format(device, cache_size) formats unconditionally, then mounts. Use only for deliberately disposable or freshly initialized storage.
  • FileSystem::get_or_format(device, cache_size) tries to mount, but formats whenever that first mount fails. It does not distinguish a blank disk from a corrupt disk, incompatible geometry or transient I/O failure. This is unsafe as an automatic recovery policy for a persistent user disk.
  • FileSystem::format(device, cache_size) explicitly formats the underlying storage without returning a mounted filesystem.

All constructors require an &'static dyn DirectBlockDevice and a cache size; they derive physical block size and count from the supplied device and build a LittleFS C configuration. Initialization populates missing root attributes. A transient lock failure during an operation may surface as RessourceBusy.

// Intentionally format an ephemeral in-memory block device for testing.
let device = file_system::MemoryDevice::<512>::new_static(512 * 1024);
let filesystem = little_fs::FileSystem::new_format(device, 256)?;

This example is suitable for disposable test data only. For existing flash/OPFS disks, prefer new and handle mount failure explicitly, without automatic destruction.

Handle lifetimes, metadata and failure behavior

Section titled “Handle lifetimes, metadata and failure behavior”

The backend wraps the mounted littlefs::lfs_t in MutexMountWrapper<CriticalSectionRawMutex, _>. Open file/directory contexts use shared Arc<Mutex<...>> state rather than duplicating raw LittleFS C caches. operation_with_context verifies the stored type and uses try_lock; a mismatch yields InvalidParameter, and contention yields RessourceBusy.

writable_attributes() advertises the specific InternalAttributes::PERSISTED_ATTRIBUTE_FLAGS. This is important: LittleFS cannot necessarily store every VFS-provided timestamp or metadata field. The backend translates file/directory operations through lfs_* and maps LittleFS error codes to file_system::Error.

A target storage driver must provide correct block geometry, read/program/erase semantics and durability on flush. Cache size and driver alignment need to fit the underlying device; using a correctly mounted VFS cannot compensate for a broken block callback.