Protected and Persistent RAM Filesystem

Introducing PRAMFS

Many embedded systems have a block of non-volatile RAM seperate from normal system memory, i.e. of which the kernel maintains no memory page descriptors. For such systems it would be beneficial to mount a read/write filesystem over this "I/O memory", for storing frequently accessed data that must survive system reboots and power cycles or volatile data avoiding to write on a disk or flash. An example usage might be system logs under /var/log or debug information of a flight-recorder.

Currently Linux has no support for a persistent, non-volatile RAM-based filesystem, persistent meaning the filesystem survives a system reboot or power cycle intact. The existing RAM-based filesystems such as tmpfs and ramfs have no actual backing store but exist entirely in the page and buffer caches, hence the filesystem disappears after a system reboot or power cycle.

A relatively straight-forward solution is to write a simple block driver for the non-volatile RAM, and mount over it any disk-based filesystem such as ext2, ext3, ext4, etc.

But the disk-based fs over non-volatile RAM block driver approach has some drawbacks:

1. Complexity of disk-based fs: disk-based filesystems such as ext2/ext3/ext4 were designed for optimum performance on spinning disk media, so they implement features such as block groups, which attempts to group inode data into a contiguous set of data blocks to minimize disk seeking when accessing files. For RAM there is no such concern; a file's data blocks can be scattered throughout the media with no access speed penalty at all. So block groups in a filesystem mounted over RAM just adds unnecessary complexity that we can consider as an unuseful overhead. A better approach is to use a filesystem specifically tailored to RAM media which does away with these disk-based features. This increases the efficient use of space on the media, i.e. more space is dedicated to actual file data storage and less to meta-data needed to maintain that file data.

2. Different problems between disks and RAM: Because PRAMFS attempts to avoid filesystem corruption caused by kernel bugs, dirty pages in the page cache are not allowed to be written back to the backing-store RAM. This way, an errant write into the page cache will not get written back to the filesystem. However, if the backing-store RAM is comparable in access speed to system memory, the penalty of not using caching is minimal. With this consideration better to move file data directly between the user buffers and the backing store RAM, i.e. use direct I/O. This prevents the unnecessary populating of the page cache with dirty pages. However direct I/O has to be enabled at every file open. To enable direct I/O at all times for all regular files requires either that applications be modified to include the O_DIRECT flag on all file opens, or that the filesystem used performs direct I/O by default.

The Persistent/Protected RAM Special Filesystem (PRAMFS) is a read/write filesystem that has been designed to address these issues. PRAMFS is targeted to fast I/O memory, and if the memory is non-volatile, the filesystem will be persistent.

In PRAMFS, direct I/O is enabled across all files in the filesystem, in other words the O_DIRECT flag is forced on every open of a PRAMFS file. Also, file I/O in the PRAMFS is always synchronous. There is no need to block the current process while the transfer to/from the PRAMFS is in progress, since one of the requirements of the PRAMFS is that the filesystem exist in fast RAM. So file I/O in PRAMFS is always direct, synchronous, and never blocks.

PRAMFS supports the execute-in-place. With Xip, instead of doing memory-to-memory copies to transfer data from/to user space from/to kernel space, read&write operations are performed directly from/to the memory. For file mappings, the RAM itself is mapped directly into userspace. Xip, in addition, speed-up the applications start-up time because it removes the needs of any copies.

PRAMFS is write protected. The page table entries that map the backing-store RAM are normally marked read-only. Write operations into the filesystem temporarily mark the affected pages as writeable, the write operation is carried out with locks held, and then the pte is marked read-only again. This feature provides protection against filesystem corruption caused by errant writes into the RAM due to kernel bugs for instance. In case there are systems where the write protection is not possible (for instance the RAM cannot be mapped with page tables), this feature can be disabled via CONFIG_PRAMFS_WRITE_PROTECT config option or at mount time.

PRAMFS supports extended attributes, ACLs, security labels and freezing.

In summary, PRAMFS is a light-weight special filesystem that is ideal for systems with a block of fast non-volatile RAM that need to access data on it using a standard filesytem interface.