Temporary and Pseudo Filesystems: Data, Interfaces, and Resource Boundaries

On this page

Paths may look like files, but their operational meanings differ significantly: tmpfs stores application data, procfs generates status information, and writing to sysfs may control devices. When reading these interfaces, first confirm their responsibilities, lifespans, and resource boundaries.

Phenomenon to ExplainWhere to Read
Is the read text a consistent snapshot?Sections 1–2: Classification and seq_file
Why can't sysfs attributes be saved using an editor?Sections 3–4: Control and tracing interfaces
Why might temporary files also touch swap?Section 5: tmpfs and memfd
What is the difference between device nodes, early root, and actual mounts?Sections 6–7: Boot and mounting

1. Classify by Responsibility First

All are file interfaces, but content sources and resource constraints differ User Data Storage tmpfs / ramfs / memfd Dynamic Observation & Control procfs / sysfs / cgroupfs Device & Debug Interfaces devtmpfs / debugfs / tracefs Memory, Swap, Quotas Data requires actual resource usage Kernel State & Callbacks Reads may not be globally consistent snapshots Drivers / Tracing Facilities Access can trigger actual device operations nodev indicates that a block device is not required as a mount source; it does not mean there is no storage, no side effects, or no permission restrictions.
FilesystemCommon ResponsibilityKey Boundaries
procfsProcess and system information, some control interfacesAffected by PID namespaces, permissions, and mount options
sysfsDevice model and kernel object attributesAttribute interfaces must adhere to ABI; not all internal structures are exported arbitrarily
debugfsDevelopment and debugging interfacesUsually does not guarantee a stable user ABI, and may be completely disabled
tracefsTracing configuration and dataReading different files may yield snapshots, blocking streams, or consumed records
tmpfsTemporary files, shared memory-related storageOccupies memory, can be swapped out depending on configuration; has space and inode limits
ramfsSimple in-memory file storageCannot be written back to release space like normal files, and lacks tmpfs-style size caps
devtmpfsKernel device nodesNode existence does not guarantee the device is currently available or accessible

The nodev flag in /proc/filesystems is not a precise label for "all pseudo-filesystems": filesystems like NFS that do not require a block device as a mount source can also be listed as nodev. It is also not equivalent to the mount option nodev, which restricts the use of device special files as devices.

2. procfs: Object Lifespans Behind Text Output

/proc/<pid>/status, maps, and fd involve task state, virtual memory mappings, and file descriptors, respectively; these objects can change or exit during the read operation. PIDs can also be reused, so reading the same numeric path multiple times does not necessarily operate on the same long-lived object. When a stable process reference is needed, one should understand interfaces like pidfd, rather than treating directory names as permanent identities.

/proc/self resolves based on the accessor. The set of processes visible in a container depends on the PID namespace associated with the proc mount; permissions, hidepid, etc., also affect visibility. Not all /proc system statistics automatically become container-specific statistics. /proc/<pid>/mem is subject to strict access checks and cannot be generalized as an alternative channel to bypass ptrace permissions. See procfs documentation.

seq_file Solves Output Organization, Not System Freezing

seq_file manages segmented output, buffering, and positioning, making it suitable for generating text from traversable objects. Callbacks such as start/next/stop/show must still adhere to the synchronization and reference rules of their respective objects. Insufficient buffering or seek operations may cause re-traversal, so show should not have non-repeatable business side effects.

A single cat command may consist of multiple read operations; whether multiple fields in the output come from the same consistent snapshot depends on the specific implementation and cannot be deduced solely from "using seq_file" to infer global atomic observation. Userspace parsers should identify keys and tolerate new fields, rather than relying on specific lines always containing specific data. See seq_file interface.

Below is an example of a standalone kernel module that outputs only constants, using proc_create_single() to reuse seq_file. It illustrates registration, failure return values, and removal pairing, without reading mutable driver objects:

#include <linux/errno.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>

static struct proc_dir_entry *entry;

static int kb_show(struct seq_file *seq, void *unused)
{
    seq_puts(seq, "format_version 1\n");
    seq_puts(seq, "example_value 42\n");
    return 0;
}

static int __init kb_init(void)
{
    entry = proc_create_single("kb_seq_example", 0444, NULL, kb_show);
    return entry ? 0 : -ENOMEM;
}

static void __exit kb_exit(void)
{
    proc_remove(entry);
}

module_init(kb_init);
module_exit(kb_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Constant seq_file teaching example");

The corresponding Kbuild behavior is obj-m += kb_seq_example.o. For teaching checks, one can compile only the object file without loading the module. If constants are changed to dynamic objects, one must still handle concurrent callbacks, background tasks, and private data lifespans during removal; copying this framework does not automatically resolve those reference relationships.

3. sysfs and kernfs: Object Attributes Are Not Ordinary Editable Files

sysfs presents kernel objects as directories, attributes, and links; /sys/devices represents the device hierarchy, and views such as bus/class are often organized via links. A kobject usually corresponds to a directory, while attributes correspond to files; one cannot say that each kobject directly equals an attribute file.

OperationWhat the Attribute Interface Actually Does
showGenerates the current value
storeValidates input and executes the corresponding change
Return successReports the interface processing result, not necessarily that any device operation has fully completed

Text attributes typically use concise and explicit values; binary attributes have their own contracts. Size, seek, and repeated reads must also be interpreted according to the interface. See sysfs design.

kernfs provides the infrastructure for trees and file operations for sysfs, cgroupfs, etc., and has existed since before version 6.x. It also needs to coordinate node deletion with ongoing operations and cannot be understood merely as "a directory tree with RCU." Its link facilities are primarily symbolic links and cannot be generalized to have arbitrary hard-link semantics like ordinary disk filesystems. The synchronization provided by the framework does not replace protection for driver-private state.

When userspace writes to control attributes, one should use the complete input format specified in the documentation, rather than using an editor's temporary file plus rename-save mode. To understand the stability and units of a specific attribute, one should prioritize finding the corresponding entry in Documentation/ABI/, rather than guessing from the filename.

4. debugfs and tracefs: Observation May Also Have Overhead and State Changes

debugfs conveniently allows developers to export data, but interfaces may change across versions and configurations. Production troubleshooting can use it according to permissions and procedures; "unstable ABI" does not mean it is absolutely unreadable in production. Drivers creating debugfs nodes must also consider device removal and data release when users hold open references.

tracefs provides a separate mount for tracing facilities. The reading methods for trace and trace_pipe differ: the latter can wait for new events and consume data, so cat may not exit quickly; modifying event switches, buffer sizes, or tracing_on will change the system tracing state. Whether a node is exposed is also subject to configuration, mounting, and permission restrictions. See debugfs and ftrace documentation.

5. tmpfs: Temporary Does Not Mean No Space, Nor Does It Mean Never Touching Disk

tmpfs uses the shmem mechanism to store user data. It does not have a block device backend like ordinary filesystems, but under configurations allowing swap, it can swap out content; thus, "data stays only in RAM and never appears on disk" is not a universal guarantee. One cannot expect it to recover like a persistent filesystem after unmounting or rebooting, even if swap was written to or fsync was called.

Four Quantities: Limits, Logical Length, Resident, and Swapped

QuantityMeaning
size=, nr_inodes=Capacity and inode count limits; does not reserve all memory
File logical sizeCan be very large after sparse extension, without necessarily allocating all content pages
Allocated pages and resident amountHow much content has been allocated, and how much is currently in RAM
Swapped amountPart of the content may be backed by swap

Mount limits, cgroups, and system pressure interact; having remaining capacity on a mount does not guarantee that memory allocation will succeed. See tmpfs documentation.

/dev/shm is often mounted as tmpfs to hold POSIX shared memory objects; /run often stores runtime state; /tmp may be tmpfs or a disk directory, so check the actual mountinfo. System V shared memory, anonymous shared mappings, etc., also use related shmem mechanisms, but do not require a visible name in /dev/shm for each.

Below, we first change the file length, then write only to a few pages. After swapping out pages, compare logical length, allocated amount, RAM, and swap: releasing RAM does not simultaneously cancel the file's allocated content accounting.

Preparing the visual
The File Is Eight Pages Long, Why Doesn't It Occupy Eight Pages of RAM?

Sparse length, filesystem allocation quota, RAM residency, and swap backing are four different accounts. Swapping out reduces residency but does not release tmpfs content allocation quotas.

memfd: Memory Files Managed via File Descriptors

Ordinary memfd_create() provides anonymous memory files that can be mmap'd, have fds passed, and can use seals to restrict subsequent modifications; MFD_HUGETLB belongs to a different backing mode and cannot be conflated with the ordinary shmem path. Seals are object-level constraints, not just changing the current fd to read-only; existing writable shared mappings, etc., also affect whether certain seals can be added.

import errno
import fcntl
import os

fd = os.memfd_create("kb-memfd", os.MFD_CLOEXEC | os.MFD_ALLOW_SEALING)
try:
    assert os.write(fd, b"hello") == 5
    seals = (fcntl.F_SEAL_WRITE | fcntl.F_SEAL_GROW |
             fcntl.F_SEAL_SHRINK | fcntl.F_SEAL_SEAL)
    fcntl.fcntl(fd, fcntl.F_ADD_SEALS, seals)
    assert fcntl.fcntl(fd, fcntl.F_GET_SEALS) & seals == seals
    assert os.pread(fd, 5, 0) == b"hello"
    try:
        os.pwrite(fd, b"X", 0)
    except OSError as error:
        assert error.errno == errno.EPERM
    else:
        raise AssertionError("sealed file unexpectedly writable")
    print("memfd content is readable, seal prevents rewrite: Passed")
finally:
    os.close(fd)

This example does not mount a filesystem or create permanent paths; it also does not demonstrate guarantees of persistence or that secret data will never be swapped out. For interface details, see memfd_create(2).

6. ramfs, rootfs, initramfs, and devtmpfs

NameRole in Boot or Storage
ramfsIn-memory file storage, no ordinary write-back backend and no tmpfs-style capacity limits
rootfsSpecial root mount required for boot, uses ramfs or tmpfs depending on configuration
initramfsArchive content and boot environment unpacked to the early root

Continuous writing to ramfs can consume system memory; initramfs is not a disk filesystem format parallel to ramfs/tmpfs. See rootfs and initramfs.

Device Nodes: Creating Nodes and Booting Hardware Should Be Viewed Separately

devtmpfs manages basic device nodes via the kernel device model, while userspace facilities like udev apply permissions, naming links, and other rules on top of events. The basic creation of nodes should not be entirely attributed to udev, nor can it be guaranteed that all boot paths have /dev automatically mounted by the kernel; kernel configuration and initramfs userspace affect the mounting process.

Device nodes are metadata such as type and device numbers; opening them enters the corresponding driver; deleting a node does not stop the hardware, and recreating a node does not guarantee the driver exists. nodev mount restrictions, permissions, and device access control still participate in authorization decisions.

7. Limit Observations to the Required Scope

QuestionPriority Check
Is /tmp actually in memory?findmnt -T /tmp and actual mount options
tmpfs is full but the system has memoryMount capacity, inode limits, and logical/actual usage
/proc/<pid> does not show the expected taskPID namespace, process lifespan, permissions, and hidepid
sysfs attribute does not existDevice instance, driver binding, kernel configuration, and ABI documentation
tracefs read does not exitWhether reading a blocking/consuming stream, and whether events are still being generated

findmnt, df -t tmpfs, and targeted attribute reads are usually sufficient to establish the first round of facts. Recursively traversing the entire /sys/devices tree is expensive and mixed; for dynamic interfaces, one should not batch-read/write just because the extension looks like an ordinary file. Source code can be located layer by layer along fs/proc/, fs/sysfs/, fs/kernfs/, mm/shmem.c, and drivers/base/devtmpfs.c.