In littlefs, moving a file between two directories cannot be done in a single atomic commit because a commit cannot span multiple directories. To prevent file duplication or loss during power-loss events, littlefs uses a mechanism called global state.
The Mechanism: Global State
Global state is a small set of data distributed across the filesystem as deltas (stored in metadata pairs). The actual global state is reconstructed by performing a bitwise XOR operation on all deltas found in the filesystem during the mount process.
Solving the Move Problem
To move a file (or directory) atomically:
- Begin Move: Create a new reference in the destination directory and update the global state with a delta describing the move (e.g.,
gstate = moving file D in dir A). - Complete Move: Remove the old reference from the source directory and update the global state with a delta that cancels out the previous move delta (e.g.,
gstate = no move).
Power-Loss Recovery
If power is lost mid-move, the file may exist in both the source and destination directories. Upon the next mount, littlefs reconstructs the global state from the deltas. If the reconstructed state indicates an ongoing move, the filesystem uses that information to identify and resolve the duplication (e.g., by removing the redundant file).