Partitions and filesystems
Listen to this lesson
This episode is a study companion for CompTIA Linux+ XK0-006 and is not produced by or endorsed by CompTIA.
Why this matters
Below LVM sits the layer that decides how a disk is divided and what structure is written onto it. Getting this wrong is expensive in a way most Linux mistakes are not: choosing xfs when you will later need to shrink, or using MBR on a 4 TB disk and silently losing 2 TB of it.
It is also where the everyday questions live — why does df disagree with du, and what do I do when the filesystem will not mount.
The lesson
Seeing what is there
lsblk # the block-device tree: disks, partitions, mounts
lsblk -f # ...with filesystem type, label and UUID
blkid # UUIDs and types, one line per device
blkid /dev/sda1
fdisk -l # partition tables on every disk
cat /proc/partitions
lsblk -f is the one to start with. It shows the whole picture — which disks exist, how they are divided, what is on each partition, and where it is mounted — in one screen.
blkid gives you the UUID, which is what belongs in /etc/fstab. Device names like /dev/sdb are assigned in detection order and can change when you add a disk or reboot; a UUID is written into the filesystem itself and does not.
Partition tables: MBR and GPT
Two schemes, and the choice has hard consequences.
MBR (msdos) is the old one. Four primary partitions, one of which can be an extended partition containing logical ones. Its fatal limit is that it uses 32-bit sector addressing, so it cannot address beyond 2 TB. Partition a 4 TB disk as MBR and the space above 2 TB is simply unreachable — with no error, just a smaller disk than you paid for.
GPT is the modern one. 128 partitions by default, addresses far beyond any current disk, and stores a backup table at the end of the disk so a corrupted primary can be recovered. UEFI firmware requires it.
Use GPT. The only reason to choose MBR is a legacy BIOS system that cannot boot from GPT.
Creating partitions
fdisk /dev/sdb # interactive; handles MBR and now GPT
gdisk /dev/sdb # GPT-specific, same interface
parted /dev/sdb # scriptable, handles both
parted -l # list everything
Inside fdisk: p print, n new, d delete, t change type, w write and exit, q quit without saving.
Nothing is written until w. That means q is a genuine escape hatch — if you have made a mess, quit and start again with the disk untouched. It also means forgetting w silently discards everything you just did.
# non-interactive, with parted
parted -s /dev/sdb mklabel gpt
parted -s /dev/sdb mkpart primary 0% 100%
partprobe /dev/sdb # tell the kernel to re-read the table
partprobe matters because the kernel caches the partition table. Change it while a partition on that disk is mounted and the kernel keeps the old view until told otherwise — which is why a new partition sometimes does not appear in /dev until you run it or reboot.
growpart /dev/sda 1 # grow partition 1 to fill the disk
growpart is the cloud-and-VM tool: after enlarging a virtual disk, the partition still ends where it did. growpart moves the boundary out, in place, on a mounted filesystem. It is the step between "the hypervisor says 200 GB" and "Linux says 200 GB", and the full chain is growpart → pvresize (if LVM) → lvextend -r → done.
Filesystems
mkfs.ext4 /dev/sdb1
mkfs.xfs /dev/sdb1
mkfs.xfs -f /dev/sdb1 # -f overwrites an existing filesystem
mkfs -t ext4 /dev/sdb1 # equivalent long form
mkfs.ext4 -L data /dev/sdb1 # with a label
The formats you need to know:
ext4 — the long-standing default on Debian and Ubuntu. Journalled, mature, extremely well understood. It can be shrunk, which xfs cannot, and that alone is a reason to choose it where sizing is uncertain.
xfs — the default on RHEL and derivatives. Excellent with large files and parallel I/O, scales to enormous filesystems, grows online. It cannot be shrunk at all. Not with tooling, not offline, not ever — you back up, recreate, restore.
btrfs — copy-on-write, with snapshots, checksumming of data and metadata, built-in multi-device support and transparent compression. Default on openSUSE and Fedora Workstation. More features, more complexity.
tmpfs — a filesystem in RAM. Fast, and lost on reboot. /dev/shm, /run and often /tmp are tmpfs. It grows as used rather than reserving memory up front, but it counts against RAM, so an unbounded tmpfs can drive a machine into swap or the out-of-memory killer.
mount -t tmpfs -o size=2G tmpfs /mnt/fast
The decision, briefly: xfs unless you might need to shrink; ext4 if you might; btrfs if you specifically want snapshots.
Resizing a filesystem
A filesystem does not notice that the space beneath it grew. Two tools, and they take different arguments — which is the detail that catches people:
resize2fs /dev/data/web # ext4 — takes the DEVICE
resize2fs /dev/data/web 50G # to a specific size
e2fsck -f /dev/data/web # required before an offline SHRINK
resize2fs /dev/data/web 20G # shrink — unmounted, ext4 only
xfs_growfs /srv/web # xfs — takes the MOUNT POINT
resize2fs grows a mounted ext4 filesystem online and shrinks it only while unmounted, after a forced check. xfs_growfs grows online and has no shrink counterpart at all.
Both are the second half of the LVM grow operation: lvextend makes the volume bigger, one of these makes the filesystem use it.
Checking and repairing
fsck /dev/sdb1 # dispatches to the right checker
fsck -y /dev/sdb1 # answer yes to everything
e2fsck -f /dev/sdb1 # ext4, forced even if it looks clean
xfs_repair /dev/sdb1 # xfs — note: NOT fsck.xfs, which does nothing
xfs_repair -n /dev/sdb1 # dry run, report only
Never run a repair on a mounted filesystem. It will corrupt it. Unmount first; if it is the root filesystem, boot from rescue media or a rescue target.
fsck.xfs exists but is deliberately a no-op — xfs is checked at mount time and repaired with xfs_repair. Reaching for fsck on xfs and seeing it do nothing is confusing until you know that.
xfs_repair refuses to run if the log is dirty, telling you to mount and unmount so the log replays. -L zeroes the log and discards whatever was in it, so it is a last resort, not a first move.
Space: df, du, and why they disagree
df -h # free space per filesystem
df -i # INODE usage
du -sh /var/log # size of a directory tree
du -h --max-depth=1 /var | sort -h # what is big in here?
df reports what the filesystem says; du adds up files it can see. They disagree in two situations, and both are exam-worthy:
A deleted file still held open. A process has the file open, so the blocks are not freed until it closes. du cannot see the file — it has no name any more — but df still counts it. Symptom: you delete a 10 GB log and nothing is freed. Find it with lsof | grep deleted, and fix it by restarting the process that holds it.
Something mounted over a non-empty directory. Files underneath the mount point still occupy space but are invisible while it is mounted.
df -i is the check people forget. A filesystem can be 20% full and completely unable to create a file, because it has run out of inodes — each file needs one, and the count is fixed at format time. Millions of tiny files (mail spools, session files, cache directories) exhaust inodes long before they exhaust blocks. "No space left on device" with df -h showing plenty free means df -i.
Benchmarking with fio
fio --name=test --rw=randread --size=1G --bs=4k --filename=/mnt/data/testfile
fio --name=w --rw=write --size=1G --bs=1M --filename=/mnt/data/testfile
fio generates controlled I/O so you can measure what storage actually does rather than guessing. It matters because the two numbers people conflate — throughput (MB/s, which sequential large-block work cares about) and IOPS (operations/second, which databases care about) — behave completely differently. A disk that streams 500 MB/s may deliver poor random 4k IOPS, and a database on it will crawl while dd looks fine.
Always benchmark with a working set larger than RAM, or you are measuring the page cache.
RAID, in brief
Redundant Array of Independent Disks combines several disks for redundancy, performance, or both. It sits below LVM and filesystems, and is covered properly in the next lesson — but the vocabulary belongs here because you choose a RAID level before you partition.
The short version: RAID 0 stripes for speed with no redundancy, RAID 1 mirrors, RAID 5 stripes with one parity disk, RAID 6 with two, RAID 10 mirrors then stripes. RAID is not a backup — it protects against a disk dying, not against deletion, corruption or ransomware, all of which replicate instantly across every disk in the array.
On the exam
- MBR cannot address beyond 2 TB; GPT can and also keeps a backup table. UEFI requires GPT.
- In
fdisk, nothing is written untilw, andqdiscards. -
xfs cannot be shrunk. ext4 can. Expect this as a scenario. -
xfs_repair, notfsck, for xfs —fsck.xfsintentionally does nothing. - Never check or repair a mounted filesystem.
-
dfversusdudisagreeing means a deleted-but-open file (find it withlsof) or something mounted over a populated directory. - "No space left" with free space showing means inodes —
df -i. - Use UUIDs rather than device names, because
/dev/sdbcan move. -
growpartthenpvresizethenlvextend -ris the grow-a-virtual-disk chain.
Practise what you just read
1. A new 8 TB disk must be fully usable as a single partition. Which partition table is required?
Select one
Show answer
C. MBR stores 32-bit sector counts, which with 512-byte sectors caps addressing at about 2 TB -- the rest of the disk is simply unreachable. GPT uses 64-bit addressing, allows 128 partitions by default, and keeps a backup table at the end of the disk. UEFI firmware requires GPT, so on modern hardware it is the answer twice over.
2. You have made several changes in fdisk and realise they are wrong. Which key leaves without applying them?
Select one
Show answer
C. fdisk works on an in-memory copy of the partition table and changes nothing on disk until w. q discards everything and exits, which makes fdisk safe to explore in -- you can add, delete and print freely as long as you remember which key ends the session. p prints the pending table before you commit.
3. touch fails with "No space left on device", but df -h shows the filesystem is 43% used. What should you check?
Select one
Show answer
D. ext filesystems are created with a fixed number of inodes, one per file, and millions of tiny files exhaust them while using almost no space. df -i shows the use percentage at 100%. The fix is deleting files, and the permanent fix is more inodes at mkfs time or moving to xfs, which allocates them dynamically.
6 more questions on this objective are part of the full course.
Hands-on labs
Part of the free CompTIA Linux+ XK0-006 course — 48 lessons and 82 hands-on labs.