Linux Disk Management: fdisk, LVM, mount and More

Tested on: Ubuntu 26.04 LTS · Debian 12 · Rocky Linux 10 — Last updated: June 2026
Disk management on Linux spans partitioning raw drives, formatting filesystems, mounting storage, managing logical volumes, and recovering from full disks. Whether you're provisioning a new data volume on a VPS, extending an LVM volume without downtime, or hunting down what consumed 200 GB overnight, these tools handle it. This guide covers lsblk, fdisk, parted, mkfs, mount, df, du, LVM, swap, and software RAID — with real commands for real situations.
Prerequisites
- Root or
sudoaccess on the target machine - Basic terminal familiarity — you know how to open a shell and run commands
- For LVM sections:
lvm2package installed (sudo apt install lvm2) - For RAID:
mdadmpackage installed (sudo apt install mdadm) - Back up any data before partitioning or formatting. These operations are destructive by design.
View Disks and Partitions
Before touching anything, get a clear picture of what storage is attached and how it's laid out.
# Best overall view — block device tree:
lsblk
# Include filesystem type, UUID, and label:
lsblk -f
# fdisk listing — shows partition types and sizes:
sudo fdisk -l
# parted — more detail on GPT disks:
sudo parted -l
# NVMe drives (not always shown by fdisk on older systems):
sudo nvme list
# Hardware-level disk info:
sudo lshw -class disk -shortA typical lsblk output on a server with an NVMe drive and LVM looks like this:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
nvme0n1 259:0 0 500G 0 disk
├─nvme0n1p1 259:1 0 512M 0 part /boot/efi
├─nvme0n1p2 259:2 0 2G 0 part /boot
└─nvme0n1p3 259:3 0 497.5G 0 part
├─vg-root 253:0 0 50G 0 lvm /
├─vg-home 253:1 0 200G 0 lvm /home
└─vg-data 253:2 0 247.5G 0 lvm /dataKey TYPE values: disk = physical device, part = partition, lvm = logical volume, raid1/raid5 = software RAID array. RM=1 means removable (USB), RO=1 means read-only.
Check Disk Space: df and du
df reports free space on mounted filesystems. du measures what's actually consuming space inside a directory tree. You need both — they answer different questions.
# All mounted filesystems, human-readable:
df -h
# Check a specific mount point:
df -h /var
# Inode usage (you can run out of inodes before running out of bytes):
df -i
# Top-level space usage, sorted largest first:
du -sh /* 2>/dev/null | sort -rh | head -10
# Drill into /var:
du -sh /var/* 2>/dev/null | sort -rh | head -20
# Size of everything in /var/log individually:
du -sh /var/log/*If df shows a filesystem full but du totals don't add up, see the Troubleshooting section — a deleted-but-open file is the likely cause.
Partition a Disk with fdisk
Use fdisk for MBR partition tables on drives under 2 TB, or when you need quick interactive partitioning. For UEFI systems or drives over 2 TB, use parted with GPT instead.
# Open fdisk on a new, unpartitioned disk:
sudo fdisk /dev/sdbInside the interactive prompt, the commands you'll use most:
Command (m for help): m # show all commands
Command (m for help): p # print current partition table
Command (m for help): n # new partition
Command (m for help): d # delete a partition
Command (m for help): t # change partition type (82=swap, 8e=Linux LVM, 83=Linux)
Command (m for help): w # write changes to disk and exit
Command (m for help): q # quit WITHOUT savingTo create a single partition that uses the entire disk: type n, accept all defaults (primary, partition 1, first/last sector), then w to write. Verify:
lsblk /dev/sdb
# NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
# sdb 8:16 0 1T 0 disk
# └─sdb1 8:17 0 1T 0 partPartition with parted (GPT)
GPT is the correct choice for any disk over 2 TB, UEFI boot drives, and modern deployments generally. parted supports both interactive and scripted modes.
# Non-interactive — create GPT label and a single partition:
sudo parted /dev/sdb --script mklabel gpt
sudo parted /dev/sdb --script mkpart primary ext4 0% 100%
# Interactive mode:
sudo parted /dev/sdb
(parted) mklabel gpt
(parted) mkpart primary ext4 0% 100%
(parted) print
(parted) quit
# Verify:
lsblk /dev/sdbAlways use percentage-based start/end values (0%, 100%) in parted — it ensures proper sector alignment, which matters for SSD and NVMe performance.
Format Filesystems
Partitioning defines boundaries. Formatting creates the filesystem structure that the OS actually uses.
| Filesystem | Command | Best For |
|---|---|---|
| ext4 | sudo mkfs.ext4 /dev/sdb1 | General Linux use — stable, mature, widest tool support |
| xfs | sudo mkfs.xfs /dev/sdb1 | Large files, databases, high-throughput — RHEL/Rocky default |
| btrfs | sudo mkfs.btrfs /dev/sdb1 | Snapshots, built-in checksums, compression |
| vfat/exfat | sudo mkfs.vfat /dev/sdb1 | USB drives, cross-platform compatibility |
| ntfs | sudo mkfs.ntfs /dev/sdb1 | Windows interoperability |
# ext4 with a label:
sudo mkfs.ext4 -L "datastore" /dev/sdb1
# ext4 with 0% reserved blocks (default is 5% — wasteful on large data volumes):
sudo mkfs.ext4 -m 0 -L "data" /dev/sdb1
# xfs with a label:
sudo mkfs.xfs -L "data" /dev/sdb1
# btrfs:
sudo mkfs.btrfs -L "snapshots" /dev/sdb1The -m 0 flag on ext4 removes the 5% reserved-for-root block allocation. On a 4 TB data volume, that's 200 GB freed — leave it at the default only on root filesystems.
Mount and Unmount
# Create a mount point and mount:
sudo mkdir -p /mnt/data
sudo mount /dev/sdb1 /mnt/data
# Explicitly specify filesystem type:
sudo mount -t ext4 /dev/sdb1 /mnt/data
# Mount read-only:
sudo mount -o ro /dev/sdb1 /mnt/data
# Remount an already-mounted filesystem read-write:
sudo mount -o remount,rw /mnt/data
# Unmount by mountpoint or device:
sudo umount /mnt/data
sudo umount /dev/sdb1
# Show all non-virtual mounts:
findmnt --real
# Alternative view:
mount | grep -v "tmpfs|cgroup|proc|sys|devpts"If umount returns "target is busy", something has the filesystem open:
# Find the offending process:
lsof /mnt/data
fuser -m /mnt/data
# Kill processes using it (use with caution):
fuser -km /mnt/dataPersistent Mounts with /etc/fstab
Manual mounts don't survive a reboot. Entries in /etc/fstab mount automatically at boot. Always use UUIDs rather than device names like /dev/sdb1 — device names can shift when you add or remove hardware.
# Get the UUID for your partition:
sudo blkid /dev/sdb1
# /dev/sdb1: LABEL="data" UUID="a1b2c3d4-e5f6-7890-abcd-ef1234567890" TYPE="ext4"Edit /etc/fstab:
sudo nano /etc/fstabAdd the line (replace UUID with yours):
UUID=a1b2c3d4-e5f6-7890-abcd-ef1234567890 /mnt/data ext4 defaults,nofail 0 2Field breakdown: device · mountpoint · filesystem type · options · dump (0=skip) · fsck pass (1=root, 2=others, 0=skip). The nofail option is critical on non-root filesystems — without it, a missing or failed drive prevents the system from booting.
# Test your fstab entry without rebooting:
sudo mount -a
# Verify it mounted:
df -h /mnt/dataLVM: Logical Volume Management
LVM adds an abstraction layer between physical disks and the filesystems that use them. The payoff: resize volumes live without repartitioning, span a single logical volume across multiple disks, and take instant point-in-time snapshots for backup.
LVM Concepts
- PV (Physical Volume): A disk or partition initialized for LVM with
pvcreate - VG (Volume Group): A named storage pool combining one or more PVs
- LV (Logical Volume): A usable slice carved from a VG — format it and mount it like a regular partition
Set Up LVM from Scratch
# Install lvm2 if not present:
sudo apt install lvm2
# Step 1 — Initialize physical volume:
sudo pvcreate /dev/sdb
sudo pvs # verify
# Step 2 — Create a volume group named "myvg":
sudo vgcreate myvg /dev/sdb
sudo vgs # verify
# Step 3 — Create logical volumes:
sudo lvcreate -L 50G -n data myvg # 50 GB for data
sudo lvcreate -L 20G -n backups myvg # 20 GB for backups
sudo lvcreate -l 100%FREE -n archive myvg # use all remaining space
sudo lvs # verify
# Step 4 — Format and mount:
sudo mkfs.ext4 /dev/myvg/data
sudo mkdir -p /mnt/data
sudo mount /dev/myvg/data /mnt/dataExtend a Logical Volume Online
This is LVM's killer feature — grow a filesystem while it's mounted and in use.
# Extend by 20 GB and resize the filesystem in one command:
sudo lvextend -L +20G --resizefs /dev/myvg/data
# Or as two separate steps:
sudo lvextend -L +20G /dev/myvg/data
sudo resize2fs /dev/myvg/data # ext4
# sudo xfs_growfs /mnt/data # xfs — pass the mountpoint, not the device
# Use all remaining free space in the VG:
sudo lvextend -l +100%FREE --resizefs /dev/myvg/data
# Add a second disk to the VG first if you need more physical space:
sudo pvcreate /dev/sdc
sudo vgextend myvg /dev/sdc
sudo vgs # confirm VFree increasedLVM Snapshots
# Create a snapshot (the -s flag, 10G of copy-on-write space):
sudo lvcreate -L 10G -s -n data-snap /dev/myvg/data
# Mount snapshot read-only for backup:
sudo mkdir -p /mnt/snap
sudo mount -o ro /dev/myvg/data-snap /mnt/snap
# Back it up, then clean up:
sudo umount /mnt/snap
sudo lvremove /dev/myvg/data-snap
# Roll back the origin volume to the snapshot state:
sudo
