Filesystems
Inodes, directories, journaling, and what really happens on open, write and fsync.
What a Filesystem Does
A filesystem turns a flat array of disk blocks into named files and directories with metadata (size, owner, permissions, timestamps). It tracks which blocks belong to which file and which blocks are free.
Inodes
On Unix filesystems, each file is an inode — a metadata record holding permissions, owner, size, timestamps, and pointers to the file’s data blocks. Crucially, the filename is not in the inode: a directory is just a table mapping names → inode numbers.
Journaling
A crash mid-write can leave the filesystem inconsistent (metadata updated, data not). A journaling filesystem (ext4, NTFS, XFS) first writes intended changes to a journal, then applies them. After a crash it replays the journal, so the filesystem is always recoverable to a consistent state.
| Mode | Journals | Trade-off |
|---|---|---|
journal | Metadata + data | Safest, slowest |
ordered | Metadata (data written first) | Good default |
writeback | Metadata only | Fastest, weakest |
What open/write/fsync Really Do
Writes don’t hit disk immediately — they land in the page cache and are flushed later. fsync() forces the data (and metadata) to durable storage, which databases call before reporting a commit.
int fd = open("data.txt", O_WRONLY | O_CREAT, 0644); write(fd, buf, len); // goes to page cache fsync(fd); // force to disk — durability close(fd);
fsync is why data "written" just before a power loss can vanish — it was still in the OS cache, not on the platter/SSD.Interview Questions
Where is a file’s name stored?
Not in the inode — in the directory entry, which maps the name to an inode number. The inode holds everything else about the file.
Hard link vs symbolic link?
A hard link is another directory entry pointing to the same inode (same file, shares data, survives the original’s deletion). A symlink is a separate small file containing a path; it breaks if the target moves.
What does journaling protect against?
Filesystem inconsistency after a crash. Changes are logged before being applied, so recovery replays or discards incomplete operations.
Why call fsync?
Because write() only updates the page cache; fsync flushes it to durable storage so a crash won’t lose the data — essential for databases and their WAL.