Part 4 · 2 chapters · ~12 min
File Systems
Files, directories and inodes, hard and symbolic links, the VFS, the page cache and writeback, fsync and durability (with measured costs), journaling and crash consistency, file descriptors and their limits, and the rename trick for atomic file updates.
9
The write path
code
ls -i report.pdf # the inode number stat report.pdf # size, blocks, link count, timestamps ln report.pdf hard.pdf # hard link: another name for the same inode ln -s report.pdf soft.pdf # symbolic link: a file containing a path
FROM write() TO THE DISK
the layers a file write passes through
swipe the figure sideways, or tap expand for full screen
1/5
VFS
The virtual file system gives one interface over every file system and many things that are not disks (/proc, sockets, pipes): "everything is a file".
one API over many file systemseverything is a file
10
Atomic updates and descriptor limits
code
// atomically replace a config file: readers see the old file or the new one, never half
const tmp = `${path}.tmp-${process.pid}`;
const fh = await fs.open(tmp, 'w'); await fh.writeFile(data); await fh.sync(); await fh.close(); // data durable
await fs.rename(tmp, path); // atomic on POSIX
const dir = await fs.open(dirname(path), 'r'); await dir.sync(); await dir.close(); // make the rename durableFile descriptors are small integers indexing a per-process table of open files, sockets and pipes. Every process has a limit (ulimit -n); leaking descriptors ends in EMFILE (Backend Debugging part 1).