FFS3 filesystem

QNX SDP8.0System ArchitectureDeveloperUser

The Flash FileSystem version 3 (FFS3) drivers implement a POSIX-like filesystem on NOR flash memory devices. This filesystem is unique to QNX OS.

The drivers are standalone executables that contain both the flash filesystem code and the flash device code. There are versions of FFS3 drivers for different embedded systems hardware as well as PCMCIA memory cards. The naming convention for the drivers is devf-system, where system describes the embedded system.

To find out what flash devices we currently support, refer to the following sources:

  • the boards and mtd-flash directories under bsp_working_dir/src/hardware/flash
  • in the QNX OS docs, the devf-* entries in the Utilities Reference

We provide the libraries and source code needed to build custom flash filesystem drivers for different embedded systems.

Organization

The FFS3 filesystem drivers support one or more logical flash drives. Each logical drive is called a socket, which consists of a contiguous and homogeneous region of flash memory. For example, consider a system containing two different types of flash device at different addresses, where one device is used for the boot image and the other for the flash filesystem. In this case, each flash device would appear in a different socket.

Each socket may be divided into one or more partitions. Two types of partitions are supported:

Raw partitions
A raw partition in the socket is any partition that doesn't contain a flash filesystem. The driver doesn't recognize any filesystem types other than the flash filesystem. A raw partition may contain an image filesystem or some application-specific data.

The filesystem will make accessible through a raw mountpoint (see below) any partitions on the flash that aren't flash filesystem partitions.

Flash filesystem partitions
A flash filesystem partition contains the POSIX-like flash filesystem, which uses a proprietary format to store the filesystem data on the flash devices. This format isn't compatible with either the Microsoft Flash File System 2 (FFS2) or the PCMCIA FTL specification.

The FFS3 filesystem allows files and directories to be freely created and deleted. It recovers space from deleted files using a reclaim mechanism similar to garbage collection.

When you start the flash filesystem driver, by default it will mount any partitions it finds in the socket. There can be only one instance of the driver per flash device, and the driver must be given the full size of the flash chip. You can specify the mountpoint (e.g., /flash) using mkefs or flashctl.

Mountpoint Description
/dev/fsX Raw mountpoint socket X
/dev/fsXpY Raw mountpoint socket X partition Y
/fsXpY Filesystem mountpoint socket X partition Y

Features

The FFS3 filesystem supports many advanced features, such as POSIX compatibility, multiple threads, background reclaim, fault recovery, endian-awareness, wear-leveling, and error-handling.

POSIX
The filesystem supports the standard POSIX functionality (including long filenames, access privileges, random writes, truncation, and symbolic links) with the following exceptions:
  • You can't create hard links.
  • Access times aren't supported (but file modification times and attribute change times are).

These design compromises allow this filesystem to remain small and simple, yet include most features normally found with block device filesystems.

Storage efficiency
The filesystem uses a fixed-size 32-byte extent header for each piece of user data stored on the filesystem. The filesystem has a 512-byte append buffer that's used to coalesce small appends to a file before flushing them out to disk. There's no other caching of user data in the filesystem (read or write). The maximum extent size is currently limited to 4096 bytes of data (plus the 32-byte header) for files which are created at runtime, although mkefs can create 16 KB extents.
Wear leveling
Wear leveling is performed on blocks within a given partition. If the flash is split into multiple partitions, then each partition has a smaller pool to level across. Blocks never migrate from one partition to another.

The most common type of reclaim in the filesystem (a foreground reclaim) always does a double-reclaim operation. The first reclaim always takes the block in the partition with the lowest erase count, and swaps it with the spare. Then the block that requires the reclaim is swapped with the spare. This has shown to result in near-perfect wear leveling when foreground reclaims are used.

Background reclaim
The FFS3 filesystem stores files and directories as a linked list of extents, which are marked for deletion as they're deleted or updated. Blocks to be reclaimed are chosen using a simple algorithm that finds the block with the most space to be reclaimed, while keeping level the amount of wear of each individual block. This wear-leveling increases the MTBF (mean time between failures) of the flash devices, thus increasing their longevity.

The background reclaim process is performed when there isn't enough free space. The reclaim process first copies the contents of the reclaim block to an empty spare block, which then replaces the reclaim block. The reclaim block is then erased. Unlike rotating media with a mechanical head, proximity of data isn't a factor with a flash filesystem, so data can be scattered on the media without loss of performance.

Fault recovery
The filesystem has been designed to minimize corruption due to accidental loss-of-power faults. Updates to extent headers and erase block headers are always executed in carefully scheduled sequences. These sequences allow the recovery of the filesystem's integrity in the case of data corruption.

Note that properly designed flash hardware is essential for effective fault-recovery systems. In particular, special reset circuitry must be in place to hold the system in reset before power levels drop below critical. Otherwise, spurious or random bus activity can form write/erase commands and corrupt the flash beyond recovery.

Rename operations are guaranteed atomic, even through loss-of-power faults. This means, for example, that if you lost power while giving an image or executable a new name, you would still be able to access the file via its old name upon recovery.

When the FFS3 filesystem driver is started, it scans the state of every extent header on the media (in order to validate its integrity) and takes appropriate action, ranging from a simple block reclamation to the erasure of dangling extent links. This process is merged with the filesystem's normal mount procedure in order to achieve optimal bootstrap timings.

Flash errors
As flash hardware wears out, its write state-machine may find that it can't write or erase a particular bit cell. When this happens, the error status is propagated to the flash driver so it can take proper action (i.e., mark the bad area and try to write/erase in another place).

This error-handling mechanism is transparent. Note that after several flash errors, all writes and erases that fail will eventually render the flash read-only. Fortunately, this situation shouldn't happen before several years of flash operation. Check your flash specification and analyze your application's data flow to flash in order to calculate its potential longevity or MTBF.

Endian awareness
The FFS3 filesystem is endian-aware, making it portable across different platforms. The optimal approach is to use the mkefs utility to select the target's endianness.

Utilities

The filesystem supports all the standard POSIX utilities such as ls, mkdir, rm, ln, mv, and cp. There are also some QNX OS utilities for managing the flash:

flashctl
Erase, format, and mount flash partitions.
mkefs
Create flash filesystem image files.

System calls

The filesystem supports all the standard POSIX I/O functions such as open(), close(), read(), and write(). Special functions such as erasing are supported using the non-POSIX devctl() function.

Page updated: