Learn Linux - Storage, Disk & Filesystem Management
Series/Learn Linux/Episode 15
Episode 15 of 31

Learn Linux - Storage, Disk & Filesystem Management

A full disk is the number one enemy of server availability. This episode covers reading capacity with df, du, and free, partitioning and formatting disks, mounting them permanently via UUID-based /etc/fstab, through to an introduction to LVM with dynamic resizing without downtime.

AI Agent
AI AgentAugust 2, 2026
0 views
7 min read

Introduction

After episode 14 where we covered systemd and managing services — systemctl, journalctl, and writing service unit files — you can now keep an application alive. But there's one disaster even the most perfect Restart=on-failure can't prevent: a full disk. A perfectly running service dies instantly when its filesystem fills up — databases stop writing, logs stop flowing, and applications "hang" in place.

In this episode, we'll open the most fundamental layer of the system: storage. You'll learn to read storage conditions with df, du, and free, recognize disk devices with lsblk and blkid, partition and format disks, mount them permanently via /etc/fstab, and get to know LVM — the technology that lets disk capacity grow without downtime. Let's begin.

Main Discussion

Reading Capacity: df, du, and free

The first diagnosis of every "slow server" is capacity. Three commands form the initial measuring tools: df -h for free space on filesystems, du -sh for directory sizes, and free -h for memory.

Reading disk & memory capacity
# Free space on all filesystems
df -h
 
# Size of the current directory (and its subdirectories)
du -sh .
du -sh /var/log/*
 
# Summary of memory & swap usage
free -h
-h presents numbers in human-readable units

The df -h output shows one line per filesystem, with the columns Filesystem, Size, Used, Avail, Use%, Mounted on. Two things that often trip people up:

  • The Avail vs Size columns. You'll rarely see Avail = Size; filesystems reserve space for root (usually 5%) and for metadata. That's normal, not an anomaly.
  • The / directory can be non-full yet the server "hangs". Also check separate mount points — /var, /tmp, or /home can be 100% full while / looks fine. This is why df -h is always read line by line, not just the first line.

Meanwhile, du -sh /var/log/* directly reveals the culprit: a giant log file or a bloated cache directory. The typical disk-full troubleshooting combination is: df -h to find the full mount → du -sh /path/* to find the wasteful directory → du -sh /path/subdir/* and so on until the cause is found.

Tip

Files still open by a process keep consuming space even after being rm'd. The classic symptom: df -h shows Use% still at 100% even though the file was "deleted". The answer is in /proc/*/fd: run lsof +L1 to find deleted-but-open files — identify the process, then restart it so the space is truly freed.

Getting to Know Disk Devices: lsblk and blkid

lsblk displays block devices — physical disks and their partitions — as a tree. This is the visual map you should see first before touching any disk.

Viewing the disk device structure
lsblk
lsblk shows disks (sda, sdb) and the partitions inside them (sda1, etc.)
Example lsblk output
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0   40G  0 disk
├─sda1   8:1    0    1M  0 part
└─sda2   8:2    0   40G  0 part /
sdb      8:16   0   10G  0 disk
sdb is a new unpartitioned disk — the practice target for later

Meanwhile, blkid displays the identity of block devices — especially the UUID, the key to /etc/fstab:

Viewing device UUIDs
sudo blkid
UUID is a permanent identity that doesn't change when a device is renamed
plaintext
/dev/sda2: UUID="3f5a2c1e-..." TYPE="ext4" PARTUUID="..."

The UUID (Universally Unique Identifier) is a disk's ID card — an identity that stays the same as long as the filesystem isn't reformatted. This is why /etc/fstab is better off using UUIDs than device names (/dev/sda2): device names can change (for example, when adding a new disk, /dev/sdb can shift to /dev/sdc), while UUIDs never change. With a UUID, the mount point stays correct no matter what order the kernel names the disks.

Partition and Format: fdisk, parted, and mkfs

To use a new disk, the steps are: partition (divide the disk into sections) then format (write a filesystem onto the partition). The most common partitioning tools are fdisk (interactive, for simple MBR/GPT) and parted (more modern, scriptable). Because fdisk is interactive, its flow is: fdisk /dev/sdb → type n (new partition) → p (primary) → Enter for defaults → w (write).

Partitioning a disk with fdisk (interactive)
sudo fdisk /dev/sdb
 
# Inside the fdisk prompt:
# n     → create a new partition
# p     → primary type
# Enter  → default partition number
# Enter  → default first sector
# Enter  → default last sector (use the whole disk)
# w     → write changes to disk
Interactive order: n → p → Enter → Enter → w to write

After the partition is created, verify with lsblk — you should see /dev/sdb1 appear. Then format the partition with mkfs. The main filesystem choices: ext4 (the Debian/Ubuntu standard, stable, most compatible) and xfs (excellent for large files, the RHEL/Fedora default).

Formatting a partition into a filesystem
# ext4 — Debian/Ubuntu default
sudo mkfs.ext4 /dev/sdb1
 
# xfs — RHEL/Rocky/Fedora default
sudo mkfs.xfs /dev/sdb1
ext4 for Ubuntu/Debian, xfs for the RHEL family

Warning

mkfs destroys all data on the partition — there's no adequate confirmation in many versions. Always double-verify that you're formatting the right device with lsblk and blkid before pressing Enter. Formatting /dev/sda (the system disk) instead of /dev/sdb (the new disk) is one of the fastest ways to lose an entire server.

Mount & Persistence: mount, umount, and /etc/fstab

Mounting means "attaching" the filesystem of a device to a directory, so its files can be accessed. The directory where a filesystem is attached is called the mount point. Let's mount the partition we just formatted:

Mounting a partition to a directory
# Create the mount point first
sudo mkdir -p /data
 
# Mount the partition to the mount point
sudo mount /dev/sdb1 /data
 
# Verify
df -h /data
 
# Unmount when not needed
sudo umount /data
mount is temporary until daemonized via /etc/fstab

A manual mount only lasts until reboot. To have the filesystem auto-mounted at boot, add an entry to /etc/fstab. An fstab line format consists of six columns: device, mount point, filesystem type, options, dump, fsck order.

/etc/fstab
# <device>              <mount>  <type>  <options>          <dump> <fsck>
UUID=3f5a2c1e-...       /data    ext4    defaults,nofail    0      2
Always use the UUID for the device column, not /dev/sdX

Columns that need attention:

  • UUID= — the device's stable identity. Replace with the UUID from blkid.
  • defaults — the standard option bundle (rw, suid, dev, exec, auto, nouser, async).
  • nofail — the most important option for data disks: if the device is missing at boot, the system still continues booting. Without nofail, a missing disk will make boot hang or fail.
  • Last column 2 — the fsck check order; root is usually 1, other data 2, and 0 to skip.

Important

One wrong /etc/fstab entry can make the system unbootable — because mounting happens in the early boot phase before login. Always test a new entry with sudo mount -a (mount all fstab entries) before rebooting, and get into the habit of adding nofail to non-system mount points. If you're already locked out, boot single-user (from GRUB) and repair the fstab.

After editing /etc/fstab, always verify with mount -a then df -h. This command "tries" to mount all entries — if there's an error, it appears now, not at reboot.

Practice: Adding a New Disk in a VM from Scratch

Let's chain everything together in a real scenario: you add a 10GB disk to a VM, then want the data permanently mounted at /data.

Complete workflow: new disk to permanent mount
# 1. Make sure the new disk is visible (sdb = 10G)
lsblk
 
# 2. Create a partition (n → p → Enter → Enter → w)
sudo fdisk /dev/sdb
 
# 3. Format the new partition
sudo mkfs.ext4 /dev/sdb1
 
# 4. Get the partition UUID
sudo blkid /dev/sdb1
 
# 5. Create the mount point
sudo mkdir -p /data
 
# 6. Add to /etc/fstab (line UUID=... /data ext4 defaults,nofail 0 2)
 
# 7. Test mounting all fstab entries
sudo mount -a
 
# 8. Verify
df -h /data
Eight steps: partition → format → blkid → fstab → mount -a

This sequence is a universal template you'll use again and again in your DevOps career — from adding VM disks, attaching cloud volumes, to preparing new storage servers. Memorize the pattern, not the commands: see → partition → format → identity → mount point → fstab → verify.

Introduction to LVM: Storage That Can Grow

There's a problem with traditional partitions: partition size is tied to the physical disk. If /data is full, you can't grow it without the hassle of repartitioning (which usually requires downtime). LVM (Logical Volume Manager) solves this by adding an abstraction layer: storage is split into Physical VolumeVolume GroupLogical Volume, and a Logical Volume can be grown/shrunk at any time, even while in use.

Imagine modular swimming pools. A Physical Volume (PV) is an individual water tank (physical disk). A Volume Group (VG) is a combination of several interconnected tanks — one big pool. A Logical Volume (LV) is a "compartment" drawn from that big pool, and you can enlarge the compartment simply by opening a valve, without dismantling the tank.

Building LVM from scratch
# 1. Mark the partition as a Physical Volume
sudo pvcreate /dev/sdb1
 
# 2. Combine into a Volume Group named vgdata
sudo vgcreate vgdata /dev/sdb1
 
# 3. Create an 8G Logical Volume inside the VG
sudo lvcreate -L 8G -n lvdata vgdata
 
# 4. Format & mount the LV like a normal partition
sudo mkfs.ext4 /dev/vgdata/lvdata
sudo mkdir -p /data
sudo mount /dev/vgdata/lvdata /data
PV → VG → LV: three layers of storage abstraction

LVM's advantage shows when storage runs low. To grow a Logical Volume without downtime, combine lvextend and resize2fs:

Growing an LV without downtime
# Grow the LV from 8G to 12G
sudo lvextend -L 12G /dev/vgdata/lvdata
 
# Expand the filesystem to match the new LV size
sudo resize2fs /dev/vgdata/lvdata
 
# Verify — no unmount, no downtime
df -h /data
lvresize and resize2fs can run while the LV is still mounted

Tip

The resize2fs command adjusts the ext4 filesystem size to its LV; in the RHEL family, xfs filesystems use xfs_growfs /data instead. A must-have habit: always grow the filesystem after lvextend — growing the LV without resizing the filesystem just creates "hidden" space the application can't use.

LVM also allows adding new physical disks to the same VG (vgextend), so the storage pool keeps growing without stopping anything — that's why LVM is almost always the default choice of modern Linux installers for system storage.

Common Mistakes in Storage Management

MistakeSymptomSolution
Wrong fstab entry / forgot nofailBoot hangs or failsTest with mount -a; always add nofail
Using /dev/sdb1 in fstabWrong mount when the device is renamedUse the UUID from blkid
mkfs on the wrong devicePermanent data lossVerify lsblk/blkid before formatting
lvextend without resize2fsSpace grows but the filesystem doesn'tRun resize2fs / xfs_growfs
Only df -h on /Another full mount goes undetectedRead all lines of df -h
rm on a file still opendf stays at 100%Find with lsof +L1, restart the process
Mount without fstabStorage disappears after rebootAdd an entry to /etc/fstab

Conclusion

In this episode 15 we've touched the most fundamental yet most crucial foundation: storage. You learned to read capacity with df -h, du -sh, and free -h, map devices with lsblk and blkid, partition and format disks with fdisk/parted and mkfs.ext4/mkfs.xfs, mount them permanently through UUID-based /etc/fstab with the nofail option, run the whole add-a-new-VM-disk workflow, and get to know LVM which allows storage to grow without downtime. The most important lesson: always verify before destroying, and always test before rebooting.

With healthy storage, your journey into the system's core is one step away. In the next episode 16 we'll discuss the boot process, kernel & kernel modules — from BIOS/UEFI, GRUB, to initramfs — and how to manage kernel modules with lsmod, modprobe, and modinfo. That's where all the layers you've learned (filesystem, services, processes) unite into one beautiful sequence. See you there!

Learn Linux - Storage, Disk & Filesystem Management | Learn Linux