<aside> 💾

Module 12 — Storage, Disks, and Filesystems

"The disk is full" is the most common Linux incident there is, and it has a dozen causes that look identical until you know how storage actually works. This module builds the whole stack from the bottom: block devices → partitions → filesystems → mounts → the abstractions (LVM, swap) on top. You'll learn to triage a full disk in under a minute, and to understand the counter-intuitive failures — space that won't free, "disk full" with space to spare — that stump people who only memorized df.

Legend used throughout: 🧠 concept → 🧩 analogy → 🧪 exercise → ✅ expected result (hidden) → 🎯 interview questions (hidden)

</aside>

<aside> 🚦

Before you start

You need Modules Module 1 — What Linux Is–Module 11 — systemd and Services — especially inodes and the file-vs-name distinction (Module 3, the key to two of this module's hardest ideas), the filesystem tree and /dev//proc (Module 2), processes holding files open (Module 8), and pipes/sort (Modules 5–7). Tools: an Ubuntu 24.04 machine. Read-only exploration (df, du, lsblk, free, findmnt) is safe to run anywhere, including inside containers. The mounting, partitioning, and LVM exercises change disks and are marked — do those only on a throwaway VM or a spare disk you can afford to wipe, never on a machine whose data you need.

Goes deeper: the kernel side of storage — the block layer, page cache, and I/O — is the companion track's Module 10 — I/O, the Block Layer & iowait.

</aside>

<aside> ℹ️

This page uses Mermaid diagram blocks. Notion shows them as code by default — click the block and set it to Preview to see the diagram. This reminder appears once per page.

</aside>

Part A — The storage stack

A1. Block devices — what a disk is to Linux

<aside> 📖

Official docs: lsblk(8)

</aside>

🧠 To Linux, a disk is a block device: a thing you read and write in fixed-size blocks, exposed as a special file under /dev. Real disks get names like /dev/sda, /dev/vda (virtio disks on VMs), or /dev/nvme0n1 (NVMe SSDs); their partitions append a number or p: /dev/sda1, /dev/nvme0n1p1. A block device is raw storage — a numbered sequence of blocks with no notion of files yet. Turning it into something you can store files on takes two more layers (partitions, then a filesystem), which the rest of Part A builds. The tool that shows the whole picture is lsblk (list block devices).

<aside> 🧩

Real-world analogy — the empty warehouse

A block device is an empty warehouse: a big space measured in numbered floor-tiles, with no shelving, no aisles, no filing system — just addressable square footage. You could pile things on the floor by tile number, but nobody works that way. The shelving and the index (partitions and a filesystem) come next.

Where the analogy stops working. A warehouse floor is visible and physical; a block device is an abstraction the kernel presents, and the "warehouse" might be a physical SSD, a slice of a SAN, a network volume, or a file pretending to be a disk — Linux treats them identically. That uniformity is powerful (the same tools work on all of them) and occasionally a trap: the /dev/vda "disk" on your cloud VM is really a slice of some storage array three racks away, with performance nothing like a local SSD.

</aside>

🧪 Exercise A1.1 — See the block devices (read-only, safe anywhere)

lsblk                    # the tree of disks, partitions, and where they're mounted
lsblk -f                 # add filesystem type, label, and usage

A2. Partitions — dividing a disk

<aside> 📖

Official docs: lsblk(8) · mount(8)

</aside>

🧠 A partition is a contiguous slice of a block device, treated as its own smaller block device. Why divide a disk: to separate concerns (keep /var/log from filling /), to run different filesystems on one disk, or to isolate swap. The partition table — the map of slices — comes in two formats: MBR (old, max 2TB, ≤4 primary partitions) and GPT (modern, huge disks, many partitions — the default now). Partitioning tools are fdisk, parted, and friends. Crucially, a partition is still raw space — slicing the warehouse into rooms doesn't install shelving; that's the filesystem, next.

<aside> ⚠️

Trap — partitioning is destructive and unforgiving. Writing a partition table rewrites the disk's map; get the device name wrong (/dev/sda when you meant /dev/sdb) and you've discarded a disk's worth of data with no undo and no confirmation beyond the one the tool gives. This is the command where "measure twice, cut once" is literal. Always lsblk first to confirm which device is which (by size, by mountpoint), never partition a mounted/in-use disk, and on production, partitioning is a change-managed operation, not something typed from memory. Every experienced engineer has one story here; the goal is to not be the story.

</aside>

<aside> 🧩

Real-world analogy — dividing the warehouse into rooms

Partitioning erects internal walls in the empty warehouse: this room for shipping, that room for cold storage, a small room for overflow. Each room is now a self-contained space you can fit out independently. The partition table is the floor plan pinned by the door.

Where the analogy stops working. Rebuilding a warehouse wall is disruptive but recoverable — the stuff inside can be moved first. Rewriting a partition table doesn't "move the stuff"; it rewrites the floor plan while pretending the rooms are empty, and the filesystem inside a repartitioned slice is simply orphaned. There is no "the movers will handle it" — you evacuate (back up) first, or you lose it.

</aside>

🧪 Exercise A2.1 — Read the partition layout (read-only, safe anywhere)

lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS    # choose exactly the columns you want
cat /proc/partitions | head                    # the kernel's raw partition list