Skip to main content

Linux Disk & Storage Management — From fdisk to LVM

· 6 min read
Goel Academy
DevOps & Cloud Learning Hub

Server says disk full but you see 50% free — here's what's actually happening. Disk management is one of those skills you don't think about until a production server runs out of space at 2 AM. Let's make sure you're ready when that happens.

Understanding Disk Usage — df and du

Before fixing anything, you need to see what's going on. These two commands are your first response tools.

# Show disk usage for all mounted filesystems (human-readable)
df -h

# Show inode usage — you can run out of inodes before disk space!
df -i

# Find the top 10 largest directories under /var
du -h --max-depth=1 /var | sort -rh | head -10

# Find files larger than 100MB anywhere on the system
find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null

Here's the secret that catches people: you can have 50% disk space free but still get "No space left on device" errors. That happens when you run out of inodes — one inode is consumed per file. A directory with millions of tiny files (like a session cache) can exhaust inodes while barely touching disk space.

CommandWhat It ShowsWhen to Use
df -hFilesystem disk spaceFirst check — overall capacity
df -iInode usage"No space" errors with free disk
du -sh *Directory sizesFinding what's eating space
lsblkBlock devices and partitionsSeeing all disks and mounts
blkidFilesystem UUIDs and typesConfiguring fstab entries

Listing and Identifying Disks

Before you partition anything, know what you're working with.

# List all block devices with size, type, and mount points
lsblk

# Show detailed partition table for a specific disk
sudo fdisk -l /dev/sda

# Get UUID and filesystem type for all partitions
sudo blkid

# Show SCSI devices (useful for identifying new disks in cloud VMs)
lsscsi

In cloud environments like AWS, new EBS volumes typically appear as /dev/xvdf or /dev/nvme1n1. Always double-check with lsblk before doing anything destructive.

Partitioning with fdisk and parted

fdisk handles MBR partitions (disks up to 2TB). For anything larger or for GPT partition tables, use parted.

# Interactive partitioning with fdisk
sudo fdisk /dev/sdb
# Inside fdisk:
# n → new partition
# p → primary
# 1 → partition number
# (accept defaults for full disk)
# w → write changes and exit

# Non-interactive partitioning with parted (GPT, full disk)
sudo parted /dev/sdb --script mklabel gpt
sudo parted /dev/sdb --script mkpart primary ext4 0% 100%

# Create a filesystem on the new partition
sudo mkfs.ext4 /dev/sdb1
ToolPartition TableMax Disk SizeBest For
fdiskMBR2 TBLegacy systems, small disks
partedGPT or MBR18 EBModern systems, large disks
gdiskGPT18 EBGPT-specific operations

Mounting and fstab

Creating a partition is useless until you mount it.

# Create a mount point and mount the partition
sudo mkdir -p /data
sudo mount /dev/sdb1 /data

# Verify it's mounted
df -h /data

# Get the UUID for fstab (never use device names in fstab — they can change!)
sudo blkid /dev/sdb1

Add a persistent mount to /etc/fstab so it survives reboots:

# Add to /etc/fstab (use UUID, not /dev/sdb1)
echo "UUID=your-uuid-here /data ext4 defaults,noatime 0 2" | sudo tee -a /etc/fstab

# Test your fstab entry without rebooting
sudo mount -a

# If mount -a succeeds with no errors, your fstab is correct

Pro tip: Always run mount -a after editing fstab. A typo in fstab can make your server unbootable.

LVM — The Real Power Tool

LVM (Logical Volume Manager) adds a flexible layer between physical disks and filesystems. You can resize volumes on the fly, span multiple disks, and take snapshots — all without downtime.

The LVM stack has three layers:

LayerAbbreviationWhat It Is
Physical VolumePVA disk or partition prepared for LVM
Volume GroupVGA pool of storage from one or more PVs
Logical VolumeLVA "virtual partition" carved from a VG
# Step 1: Create Physical Volume from a disk
sudo pvcreate /dev/sdc

# Step 2: Create a Volume Group (pool of storage)
sudo vgcreate data-vg /dev/sdc

# Step 3: Create a Logical Volume (use 80% of the VG)
sudo lvcreate -l 80%VG -n app-data data-vg

# Step 4: Create filesystem and mount
sudo mkfs.ext4 /dev/data-vg/app-data
sudo mkdir -p /app/data
sudo mount /dev/data-vg/app-data /app/data

Extending LVM Volumes — The Killer Feature

This is why LVM exists. Your /app/data is full? Add more space without unmounting.

# Scenario: Add a new disk to an existing volume group
sudo pvcreate /dev/sdd
sudo vgextend data-vg /dev/sdd

# Check available space in the volume group
sudo vgdisplay data-vg | grep "Free"

# Extend the logical volume by 50GB
sudo lvextend -L +50G /dev/data-vg/app-data

# Resize the filesystem to use the new space
# For ext4:
sudo resize2fs /dev/data-vg/app-data

# For XFS (cannot shrink, only grow):
sudo xfs_growfs /app/data

You can even do this in one command:

# Extend LV and resize filesystem in one shot
sudo lvextend -L +50G --resizefs /dev/data-vg/app-data

Managing Swap Space

Swap acts as overflow memory. Here's how to add it when your server is running low on RAM.

# Check current swap
swapon --show
free -h

# Create a 4GB swap file
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

# Make it permanent
echo "/swapfile none swap sw 0 0" | sudo tee -a /etc/fstab

# Verify
free -h

To adjust how aggressively the kernel uses swap:

# Check current swappiness (default is 60)
cat /proc/sys/vm/swappiness

# Set to 10 for servers (prefer RAM, use swap only when necessary)
sudo sysctl vm.swappiness=10

# Make permanent
echo "vm.swappiness=10" | sudo tee -a /etc/sysctl.conf

Emergency: Disk Full Recovery

When a production disk is 100% full, you need a quick fix before you can even log in properly.

# Find and delete large log files (careful!)
sudo find /var/log -name "*.log" -size +500M -exec ls -lh {} \;

# Truncate a huge log file without deleting it (keeps the file handle valid)
sudo truncate -s 0 /var/log/large-application.log

# Find deleted files still held open by processes (this is the hidden space eater!)
sudo lsof | grep deleted | sort -k7 -rn | head -10

# Restart the process holding the deleted file to reclaim space
sudo systemctl restart the-guilty-service

# Clean package manager cache
sudo apt clean # Debian/Ubuntu
sudo yum clean all # RHEL/CentOS

The lsof | grep deleted trick is the one most people miss. A process can hold a file handle to a deleted file, and the space won't be reclaimed until that process releases it. This is often why df shows full but du shows less usage.


Next up in our Linux series: Systemd Deep Dive — learn how to create services that restart automatically, replace cron with systemd timers, and understand the Linux boot process.