28/32 · 6 min
How a file is actually stored
A file looks like a continuous run of bytes. Underneath it is a set of scattered blocks and a structure that records which ones.
The inode
Everything about a file except its name:
inode 4521
type, permissions, owner
size, timestamps
link count
block pointers: [12 direct][1 indirect][1 double][1 triple]The name lives in the directory, which is just a file containing name to inode number pairs. That separation explains several things at once:
- A hard link is a second directory entry pointing at the same inode. Both names are equally real; there is no original.
- Deleting removes a name and decrements the link count. The data goes when the count reaches zero.
- A file open by a process is not freed even when unlinked, which is why deleting a log a process is writing does not reclaim the space until the process closes it.
- Renaming within a filesystem is instant: one directory entry changes.
Why the pointers are structured oddly
Twelve direct pointers cover small files with one lookup, and small files are the overwhelming majority. Larger files reach a block full of pointers, then a block of blocks of pointers. A 4KB block holding 1,024 pointers gives:
direct 12 blocks 48 KB
single indirect 1,024 blocks 4 MB
double indirect 1,048,576 blocks 4 GB
triple over a billion 4 TBFast for the common case, unbounded for the rare one.
Allocation strategies
| Strategy | Random access | Fragmentation | Used by |
|---|---|---|---|
| Contiguous | excellent | severe external | CD-ROM |
| Linked list | terrible, must walk | none | FAT, via a table |
| Indexed (inodes) | good | manageable | ext4, most Unix |
| Extents | excellent | low | ext4, NTFS, XFS |
Extents are the modern refinement: instead of listing every block, record start plus length. A 1GB contiguous file needs one extent rather than 262,144 pointers.
Journaling
A crash midway through a multi step update leaves the structure inconsistent: a block marked used by nothing, or a directory entry pointing at a freed inode. Checking a large filesystem at boot to find these took hours.
A journal applies the write ahead logging idea from databases. Write the intended change to a log, then apply it. After a crash, replay the log. Recovery becomes seconds.
Most filesystems journal metadata only by default. Structure is guaranteed consistent; file contents may still be partially written. Full data journaling is available and roughly halves write throughput, because everything is written twice.