Disk & Storage Management
Storage is where 'the server lost its data' becomes a headline. Learn to inspect devices and space (lsblk, fdisk -l, blkid, df, du), then the full journey of adding storage to Linux — partitioning with fdisk, formatting with mkfs, mounting, LVM for resizable volumes, and swap — ending with the decision flow that tells you exactly which tool to use when.
What is this?
Disk-full incidents are the most common avoidable outage, and every DevOps engineer owns the journey from a raw disk to a mounted, boot-persistent filesystem. This topic covers the inspection commands (lsblk, fdisk -l, blkid, df, du), then the tools that partition, format, mount and grow storage (fdisk, mkfs, mount, LVM), plus swap — and finishes with a decision flow so you know instantly whether a situation calls for fdisk, mount, or the full setup.
Why do you need it?
- 'No space left on device' is a routine production emergency — df -h and du are the first two commands you will type in an incident.
- Adding a disk, growing a filesystem or enabling swap is a standard SRE task you must be able to do without Googling.
- Understanding LVM turns 'we are out of disk' from an outage into a 30-second lvextend with zero downtime.
- lsblk teaches you to reason about containers, VMs and cloud volumes, because all of them are block devices under the hood.
Mental model
Adding a bookshelf to your house
Adding a disk to Linux
The raw disk is the empty shelf. Partitioning decides how many shelves you cut, formatting labels them so you can actually find things, mounting carries the shelf into the room where you can reach it, and an /etc/fstab entry tells the house to keep it there every morning.
How it works
- Linux exposes every storage device as a block device under /dev — /dev/sda, /dev/sdb — where each letter is a whole physical or virtual disk.
- Partitioning divides a disk into logical regions like /dev/sda1 and /dev/sda2, letting one disk hold the root filesystem, data and swap at once.
- mkfs writes a filesystem (ext4, XFS) onto a partition, creating the structures that store files — you cannot mount a partition until it is formatted.
- Mounting attaches that filesystem to a directory called a mount point; the same filesystem can be mounted read-only or read-write.
- LVM layers virtual volumes above physical disks, so logical volumes can be resized, moved or snapshotted without touching the hardware.
From a raw disk to a usable, boot-persistent filesystem — the fdisk vs mount decision flow.
Key commands
lsblkShow block devices as a tree — which disk owns which partition and where things are mounted.
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 100G 0 disk ├─sda1 8:1 0 96G 0 part / └─sda2 8:2 0 4G 0 part [SWAP] sdb 8:16 0 20G 0 disk
sudo fdisk -l /dev/sdaPrint the partition table of a specific disk (requires root).
Disk /dev/sda: 100 GiB, 107374182400 bytes, 209715200 sectors Device Boot Start End Sectors Size Id Type /dev/sda1 * 2048 201326591 201324544 96G 83 Linux
sudo blkid /dev/sda1Show the filesystem UUID and type — what /etc/fstab should reference.
/dev/sda1: UUID="8d5c8a24-1b2f-4e6a-9c3d-5a6b7c8d9e0f" TYPE="ext4"
df -hShow free and used space on every mounted filesystem, in human-readable sizes.
Filesystem Size Used Avail Use% Mounted on /dev/sda1 96G 41G 51G 45% / /dev/vg_data/lv_www 20G 6.4G 12.9G 34% /srv/www
du -sh /var/logShow the total size of a directory tree, one summary line.
1.2G /var/log
du -h --max-depth=1 /var | sort -hFind which subdirectory is eating the space, smallest to largest.
40K /var/tmp 1.2G /var/log 6.4G /var/lib
sudo fdisk /dev/sdbOpen the interactive partition editor — n creates a partition, w writes the changes.
Welcome to fdisk (util-linux 2.37.2). Command (m for help): n Partition number (1-4, default 1): 1 Command (m for help): w The partition table has been altered.
sudo mkfs.ext4 /dev/sdb1Format a partition with the ext4 filesystem — destructive; it erases the partition's contents.
mke2fs 1.47.0 (5-Feb-2023) Creating filesystem with 5242880 4k blocks and 1310720 inodes Writing superblocks and filesystem accounting information: done
sudo mount /dev/sdb1 /data && mount | grep /dataAttach the filesystem at /data and confirm the mount with its options.
/dev/sdb1 on /data type ext4 (rw,relatime)
sudo pvcreate /dev/sdb1 && sudo vgcreate vg_data /dev/sdb1 && sudo lvcreate -L 10G -n lv_www vg_dataThe LVM pipeline: declare a physical volume, bundle volumes into a group, carve out a logical volume.
Physical volume "/dev/sdb1" successfully created. Volume group "vg_data" successfully created Logical volume "lv_www" created.
sudo mkswap /dev/sdb2 && sudo swapon /dev/sdb2 && free -hCreate a swap filesystem, activate it, and verify it in the memory summary.
Setting up swapspace version 1, size = 4 GiB
total used free shared buff/cache available
Mem: 15Gi 2.1Gi 9.8Gi 180Mi 3.3Gi 12Gi
Swap: 4.0Gi 0B 4.0GiExamples
Attach a brand-new disk and make it survive a reboot
# 1. Find the new disk — look for a device with no partitionslsblk # 2. Partition it interactively: n (new) → accept defaults → w (write)sudo fdisk /dev/sdb # 3. Confirm the partition existslsblk # 4. Format it as ext4sudo mkfs.ext4 /dev/sdb1 # 5. Create a mount point and mountsudo mkdir -p /datasudo mount /dev/sdb1 /datadf -h /data # 6. Make it persist — use the UUID, not the device namesudo blkid /dev/sdb1echo "UUID=<uuid-from-blkid> /data ext4 defaults,noatime 0 2" | sudo tee -a /etc/fstab # 7. Validate the fstab entry without rebootingsudo mount -aThe flow is always lsblk → fdisk → mkfs → mount. The final two steps are the production difference: mounting by UUID means a device reordering at boot cannot cause data to appear on the wrong disk, and sudo mount -a proves the fstab line is valid before a typo strands the server in emergency mode.
In production
- Cloud VMs boot from a root volume; attaching an EBS or Azure disk surfaces as a new block device you partition, format and mount exactly as above.
- LVM is the default on many enterprise distros precisely because logical volumes can be grown live with lvextend — no downtime.
- Monitoring alerts on df -h usage (for example > 80%) are the standard first line of defence against disk-full outages.
- Databases commonly live on XFS or ext4 with noatime to reduce write amplification; the filesystem choice is a design decision, not a habit.
Best practices
- Always run lsblk before touching a device — formatting the wrong disk is unrecoverable data loss.
- Reference devices by UUID in /etc/fstab, never bare names like /dev/sda1 that can change at boot.
- Use -h for humans: df -h, du -sh, and mount with explicit options like mount -o noatime.
- Unmount before resizing or removing storage: umount /data first, then resize or detach.
- Leave headroom in an LVM volume group (vgdisplay) so volumes can grow later without downtime.
- Validate every fstab edit with sudo mount -a before rebooting.
Common mistakes
- Formatting the wrong device because you trusted memory instead of lsblk output.
- Trying to mount a partition before it is formatted — 'wrong fs type, bad option, bad superblock'.
- Mounting over a directory that already holds files, silently hiding them behind the mount point.
- Adding an fstab entry with the wrong UUID and booting straight into emergency mode.
- Thinking df and du disagree is a bug: deleted-but-open files still hold space until the process closes them.
Common issues
mount: wrong fs type, bad option, bad superblock on /dev/sdb1The partition was never formatted, or was formatted with a different filesystem than expected.
Confirm with lsblk -f, then format the partition (mkfs.ext4 /dev/sdb1 — this destroys data) and mount again.
mount: /data: mount point does not existThe mount point directory was never created.
Run sudo mkdir -p /data and mount again — mount never creates the directory for you.
umount: /data: target is busyA process is still reading or writing files on the filesystem.
Find it with lsof /data or fuser -m /data, stop the processes, then umount /data.
No space left on device, but du accounts for far less than df reportsA process is holding a deleted file open, or the 5% root-reserved block allowance is full.
Run lsof +L1 to find the process and restart it, or inspect reserved blocks with tune2fs -l /dev/sda1.
Debugging tips
- When df and du disagree, a deleted open file or an unmounted filesystem is almost always involved.
- dmesg | tail reveals the kernel's real reason for a failed mount — user errors hide the detail.
- fsck -f repairs a damaged ext4 filesystem, but only on an unmounted partition.
- lsof +L1 lists processes holding deleted files that still consume disk space.
Interview checkpoint
Hands-on lab
- Inspect block devices and filesystem usage with lsblk, df and du
- Create a raw disk image with dd
- Format the image with mkfs.ext4
- Mount the image, write data to it and verify persistence
- Measure directory sizes with du
Create, format and mount a filesystem image
20 min · advanced
Quick quiz
Which command displays block devices as a tree, showing which disk owns each partition?
A partition must be ______ before it can be mounted.
Which command formats a partition with the XFS filesystem?
Which LVM command creates a 10G logical volume named lv_www inside the volume group vg_data?
Running sudo mount /dev/sdb1 /data alone makes the mount persist across reboots.
You mounted a newly formatted partition to /data, wrote files, and after a reboot /data is empty. What is the most likely cause?
Cheat sheet
lsblkBlock device tree with mount pointslsblk -fAdd filesystem type and UUIDsudo fdisk -lRaw partition tablessudo blkidUUIDs and filesystem types of all devicesdf -hFree space per mounted filesystemdu -sh /pathTotal size of a directorydu -h --max-depth=1 / | sort -hFind the biggest subdirectorysudo fdisk /dev/sdbInteractive partitioning: n then wsudo mkfs.ext4 /dev/sdb1Format as ext4 (destructive)sudo mkfs.xfs /dev/sdb1Format as XFS (destructive)sudo mkdir -p /dataCreate the mount point firstsudo mount /dev/sdb1 /dataMount a filesystemsudo umount /dataUnmount (must not be in use)sudo mount -o remount,rw /dataRemount read-writesudo mount -aMount everything in /etc/fstabsudo blkid /dev/sdb1Grab the UUID for fstab/etc/fstab: UUID=... /data ext4 defaults,noatime 0 2Boot-persistent mount by UUIDsudo mount -aValidate the fstab edit before rebootingsudo pvcreate /dev/sdb1Declare a physical volumesudo vgcreate vg_data /dev/sdb1Bundle volumes into a groupsudo lvcreate -L 10G -n lv_www vg_dataCarve out a logical volumesudo lvextend -L +5G /dev/vg_data/lv_wwwGrow a volume (then resize the filesystem)sudo vgdisplayCheck free space in the volume groupsudo mkswap /dev/sdb2 && sudo swapon /dev/sdb2Create and enable swapsudo swapoff /dev/sdb2Disable swapfree -hVerify swap in the memory summary