Linux Disk Management: fdisk, LVM, mount and More

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.

Contents
  1. Prerequisites
  2. View Disks and Partitions
  3. Check Disk Space: df and du
  4. Partition a Disk with fdisk
  5. Partition with parted (GPT)
  6. Format Filesystems
  7. Mount and Unmount
  8. Persistent Mounts with /etc/fstab
  9. LVM: Logical Volume Management
    1. LVM Concepts
    2. Set Up LVM from Scratch
    3. Extend a Logical Volume Online
    4. LVM Snapshots
    5. Further Reading

Prerequisites

  • Root or sudo access on the target machine
  • Basic terminal familiarity — you know how to open a shell and run commands
  • For LVM sections: lvm2 package installed (sudo apt install lvm2)
  • For RAID: mdadm package 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 -short

A 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   /data

Key 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/sdb

Inside 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 saving

To 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 part

Partition 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/sdb

Always 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.

FilesystemCommandBest For
ext4sudo mkfs.ext4 /dev/sdb1General Linux use — stable, mature, widest tool support
xfssudo mkfs.xfs /dev/sdb1Large files, databases, high-throughput — RHEL/Rocky default
btrfssudo mkfs.btrfs /dev/sdb1Snapshots, built-in checksums, compression
vfat/exfatsudo mkfs.vfat /dev/sdb1USB drives, cross-platform compatibility
ntfssudo mkfs.ntfs /dev/sdb1Windows 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/sdb1

The -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/data

Persistent 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/fstab

Add the line (replace UUID with yours):

UUID=a1b2c3d4-e5f6-7890-abcd-ef1234567890  /mnt/data  ext4  defaults,nofail  0  2

Field 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/data

LVM: 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/data

Extend 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 increased

LVM 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


Go up