On this page
Temporary and Pseudo Filesystems
Coverage: procfs/sysfs/debugfs/tracefs → tmpfs (shmem) → devtmpfs → ramfs → kernfs framework → filesystem implementation approaches (pseudo vs. real) Kernel versions: 2.6 ~ 6.x
Overview
"Pseudo-filesystems" do not store data on disk—their data is dynamically generated by the kernel upon access. The most common examples are /proc (process information), /sys (device model), and /sys/kernel/debug (debug interfaces). They appear as regular files, but a read() call triggers callback functions in the kernel rather than disk I/O.
The core value of pseudo-filesystems is to provide a unified, tool-friendly interface. cat /proc/meminfo is more intuitive than using system calls, ioctl, or special device files.
procfs: Process Information
// fs/proc/
// /proc/<pid>/ directory for each process:
// task_struct → proc_dir_entry → inode → dentry
// Accessing a file → triggers proc-specific read handler
// Example: /proc/<pid>/status
static const struct file_operations proc_status_operations = ;
// seq_file interface (fs/seq_file.c):
// A generic framework simplifying kernel text output generation
// Automatically handles buffering, paging, and seeking
// .start() / .next() / .stop() / .show()
// Implementation: task_state() → seq_printf() outputs each field
// The process sees a plain text file, but the content is generated in real-time
Key proc Files
// /proc/<pid>/maps: VMA list (iterates mm->mmap)
// /proc/<pid>/smaps: Detailed memory statistics per VMA
// /proc/<pid>/fd/: Symbolic links for each fd → file path
// /proc/<pid>/attr/: Security attributes (SELinux/AppArmor)
// /proc/<pid>/mem: Process memory read/write (alternative to ptrace)
sysfs: Device Model
// fs/sysfs/
// sysfs is based on the kernfs framework (refactored in 6.x+)
// Each kobject → one sysfs directory/file
// kernfs_node is the core of sysfs:
;
// sysfs attribute files:
// .show(): cat /sys/... → generates text
// .store(): echo xxx > /sys/... → parses and applies
// Tree structure of the device model:
// /sys/devices/ ← Real device tree
// /sys/bus/ ← Bus types → links to devices/
// /sys/class/ ← Categorized by function → links to devices/
// /sys/block/ ← Block devices
debugfs / tracefs
// fs/debugfs/
// Unstable API: Debug interface for developers
// Not relied upon in production systems (content/paths may change across versions)
struct dentry *;
// tracefs (fs/tracefs/):
// Mount point for ftrace / tracepoints
// /sys/kernel/tracing/ ← tracefs is mounted here
// Replaces the old /sys/kernel/debug/tracing (debugfs)
tmpfs: Memory Filesystem
// mm/shmem.c
// tmpfs = shmem filesystem
// Mount: mount -t tmpfs tmpfs /tmp
// Data is stored in page cache (anonymous pages + swap-backed)
// No disk backing → data lost on power failure
// Supports swap: writes to swap when memory is tight
// Use cases:
// /tmp: Temporary files
// /dev/shm: POSIX shared memory
// /run: PID files and sockets for daemons
// /var/run: Backward-compatible symbolic link → /run
// Features:
// Auto-growing (upper limit: size mount option, or 50% of RAM)
// Supports POSIX ACL, xattr, O_TMPFILE
devtmpfs
// drivers/base/devtmpfs.c
// Dynamic device node management for /dev
// At kernel boot: devtmpfs is mounted → populated with known devices (e.g., /dev/sda, /dev/tty)
// Device hotplug: udev receives uevent notifications → creates/removes device nodes
// devtmpfs ensures that even during early boot (before udev is running)
// basic device nodes are available
// Handled automatically by kernels 2.6.32+
ramfs
// fs/ramfs/
// Extremely simple memory filesystem
// No swap backing → data always stays in memory
// No size limit → can exhaust memory (dangerous!)
// No complexity of inode operations → shortest code
// Source code is only ~200 lines (inode.c + file-mmu.c)
// Mainly used in specific scenarios (inside initramfs, rootfs)
kernfs Framework (6.x+)
// fs/kernfs/
// Shared lower-level layer for sysfs and cgroupfs
// Provides:
// 1. Hierarchical namespace (directory tree)
// 2. File operations (read/write/mmap/poll)
// 3. Symbolic and hard links
// 4. RCU-safe traversal
// Why is kernfs needed?
// The old sysfs and cgroupfs independently implemented their own VFS glue layers
// → Duplicated code, each with its own bugs
// kernfs unifies VFS interaction → reduces duplication, improves reliability
Approaches to Implementing Pseudo-Filesystems
Approach 1: seq_file (for text output in proc)
→ Suitable for: /proc/<pid>/status and other text generated line-by-line
Approach 2: kernfs (for sysfs/cgroupfs)
→ Suitable for: Attribute files (.show/.store), tree structures
Approach 3: debugfs (for debugging)
→ Suitable for: Simple file_operations registration
Approach 4: libfs (simple filesystem)
→ Suitable for: Pseudo-filesystems with only a few files
→ fs/libfs.c: simple_fill_super(), simple_lookup_dir(), ...
→ Minimal glue code
Debugging
# proc filesystem statistics
|
# sysfs device tree
# tmpfs usage
# Usage of debugfs in kernel (requires root)
References and Further Reading
- Kernel Documentation:
Documentation/filesystems/proc.rst,Documentation/filesystems/sysfs.rst,Documentation/filesystems/tmpfs.rst,Documentation/filesystems/debugfs.rst - Source Code:
fs/proc/— procfsfs/sysfs/— sysfsfs/kernfs/— kernfs frameworkfs/debugfs/— debugfsmm/shmem.c— tmpfsdrivers/base/devtmpfs.c— devtmpfsfs/libfs.c— Simple filesystem utilities
Keywords: procfs, sysfs, debugfs, tracefs, tmpfs, devtmpfs, kernfs, seq_file, pseudo-filesystem