TL;DR — Quick Summary

Linux disk partitioning with fdisk and parted: create MBR and GPT partition tables, format filesystems, mount persistently with UUID in /etc/fstab.

Linux disk partitioning is a fundamental skill for any sysadmin or DevOps engineer. Whether you are adding a data disk to a server, setting up a new installation, or preparing storage for a database, understanding how to partition disks with fdisk and parted — and how to persist mounts in /etc/fstab using UUIDs — will save you from costly mistakes and downtime. This guide covers the full workflow from raw disk to mounted, auto-mounting filesystem.

Prerequisites

  • Root or sudo access on a Linux system
  • A raw disk or virtual disk attached to the machine (e.g., /dev/sdb)
  • Basic familiarity with the Linux terminal
  • util-linux package installed (provides fdisk, lsblk, blkid — present by default on most distros)
  • parted installed: apt install parted or dnf install parted

MBR vs GPT: Choosing the Right Partition Table

Before touching a disk, you need to decide which partition table format to use. The two standards are MBR (Master Boot Record) and GPT (GUID Partition Table).

Feature MBR GPT
Max disk size 2 TB 9.4 ZB (effectively unlimited)
Max primary partitions 4 (or 3 primary + extended) 128
Boot firmware BIOS UEFI (also works with BIOS via hybrid)
Redundancy None Backup header at end of disk
OS support All Linux, Windows XP+ Linux kernel 2.6.25+, Windows Vista+, macOS
Tool support fdisk, parted, gdisk parted, gdisk, fdisk (since util-linux 2.23)
Recovery More difficult Backup GPT header enables recovery

Rule of thumb: Use GPT for any new disk in 2025. GPT’s 128-partition limit, resilience via backup header, and lack of the 2 TB ceiling make it the right default. Only use MBR when targeting very old systems or embedded hardware that specifically requires it.

Partitioning with fdisk

fdisk is an interactive, menu-driven tool included in util-linux. Modern versions (util-linux 2.23+) support GPT, making it a flexible choice for most workloads.

Inspect existing disks

# List all block devices with sizes and types
lsblk

# Show detailed partition information
fdisk -l

# Show a specific disk
fdisk -l /dev/sdb

Create a GPT partition with fdisk

sudo fdisk /dev/sdb

Inside the interactive prompt:

Command (m for help): g        # Create a new GPT partition table (use 'o' for MBR)
Created a new GPT disklabel (GUID: ...).

Command (m for help): n        # New partition
Partition number (1-128, default 1): 1
First sector (2048-..., default 2048): [Enter]
Last sector, +/-sectors or +/-size{K,M,G,T,P}: +100G   # Size the partition

Command (m for help): t        # Change partition type (optional)
Selected partition 1
Partition type or alias (type L to list all): 20   # Linux filesystem

Command (m for help): p        # Preview the partition table before writing

Command (m for help): w        # Write changes and exit

After writing, the kernel is notified. If it is not, run partprobe /dev/sdb or udevadm settle to force a re-read.

Key fdisk commands

Key Action
m Show help menu
g New GPT partition table
o New MBR partition table
n New partition
d Delete partition
t Change partition type
p Print partition table
w Write and exit
q Quit without saving

Partitioning with parted

parted supports both MBR and GPT and is scriptable — ideal for automation scripts and provisioning tools like Ansible or Terraform. It also handles disks larger than 2 TB without issue.

Interactive mode

sudo parted /dev/sdb
(parted) mklabel gpt                  # Create GPT partition table
(parted) mkpart primary ext4 0% 100%  # Single partition spanning the whole disk
(parted) print                        # Verify
(parted) quit

Non-interactive (scriptable) mode

# Create GPT table
sudo parted -s /dev/sdb mklabel gpt

# Create a single partition using 100% of disk space
sudo parted -s /dev/sdb mkpart primary ext4 0% 100%

# Create two partitions: 50 GB data, remainder logs
sudo parted -s /dev/sdb mkpart primary ext4 0% 50GB
sudo parted -s /dev/sdb mkpart primary ext4 50GB 100%

The -s flag suppresses interactive prompts, making parted safe to use in automation.

parted alignment

Always use percentage-based boundaries (0%, 100%, 50%) or MiB/GiB values rather than raw sector numbers. This ensures proper 4K sector alignment, which matters for SSD and NVMe performance.

# Verify alignment after creating partitions
sudo parted /dev/sdb align-check optimal 1
# Output: 1 aligned

Formatting Partitions with mkfs

After creating a partition, you must create a filesystem on it. The choice of filesystem depends on your workload.

# ext4 — general purpose, most compatible
sudo mkfs.ext4 /dev/sdb1

# xfs — high-performance, preferred for large files and databases
sudo mkfs.xfs /dev/sdb1

# btrfs — copy-on-write, snapshots, compression
sudo mkfs.btrfs /dev/sdb1

# Add a label (makes fstab entries more readable)
sudo mkfs.ext4 -L data /dev/sdb1
Filesystem Best For Max File Size Max Volume Size
ext4 General purpose, VM disks 16 TB 1 EB
xfs Databases, large files 8 EB 8 EB
btrfs Snapshots, NAS, home servers 16 EB 16 EB
vfat/FAT32 USB drives, EFI partitions 4 GB 2 TB

Mounting and Persistent Mounts with /etc/fstab

A partition mounted manually disappears after reboot. To persist the mount, add it to /etc/fstab. Always use UUIDs rather than device names like /dev/sdb1 — device names can change after reboots or when disks are added or removed.

Get the UUID

sudo blkid /dev/sdb1
# Output: /dev/sdb1: UUID="a1b2c3d4-..." TYPE="ext4" PARTLABEL="primary"

# Alternative: show all block device UUIDs
lsblk -o NAME,UUID,FSTYPE,SIZE,MOUNTPOINT

Create the mount point and mount immediately

sudo mkdir -p /mnt/data
sudo mount /dev/sdb1 /mnt/data

# Verify
df -h /mnt/data

Add to /etc/fstab

Open /etc/fstab with your editor:

sudo nano /etc/fstab

Add a line using this format:

# <device>                                <mountpoint>  <type>  <options>         <dump> <pass>
UUID=a1b2c3d4-e5f6-7890-abcd-ef1234567890  /mnt/data     ext4    defaults,nofail   0      2

Critical options explained:

Option Meaning
defaults rw, suid, dev, exec, auto, nouser, async
nofail Boot succeeds even if disk is absent (essential for non-root disks)
noatime Skip access time updates — improves SSD lifespan and performance
0 (dump) 0 = do not dump; 1 = include in dump backup
2 (pass) fsck order: 0 = skip, 1 = root only, 2 = check after root

Verify the fstab entry without rebooting

# Unmount first
sudo umount /mnt/data

# Test fstab (mounts all entries)
sudo mount -a

# Confirm
df -h /mnt/data

If mount -a returns no errors, the entry is valid and will survive a reboot.

Real-World Scenario: Adding a Data Disk to a Production Web Server

You have a production web server running Ubuntu 22.04. The root disk is nearly full because /var/www has grown to 180 GB. You attach a new 500 GB SSD as /dev/sdb and want to move web content to it without downtime.

Step 1 — Identify and partition the new disk:

lsblk
# Confirm /dev/sdb is the new 500GB disk with no partitions

sudo parted -s /dev/sdb mklabel gpt
sudo parted -s /dev/sdb mkpart primary ext4 0% 100%
sudo partprobe /dev/sdb

Step 2 — Format and label:

sudo mkfs.ext4 -L webdata /dev/sdb1

Step 3 — Copy existing data to the new disk:

sudo mkdir /mnt/newwww
sudo mount /dev/sdb1 /mnt/newwww
sudo rsync -av --progress /var/www/ /mnt/newwww/

Step 4 — Swap the mount (with minimal downtime):

sudo umount /mnt/newwww

# Get UUID
sudo blkid /dev/sdb1

# Edit /etc/fstab — add the new mount for /var/www
# UUID=xxxx-xxxx  /var/www  ext4  defaults,nofail,noatime  0  2

# Move old data out of the way and remount
sudo mv /var/www /var/www.bak
sudo mkdir /var/www
sudo mount -a

# Verify web server can read files
ls /var/www

Step 5 — Validate and clean up:

df -h /var/www
# /dev/sdb1  500G  180G  320G  36%  /var/www

# After confirming everything works, remove backup
sudo rm -rf /var/www.bak

Gotchas and Edge Cases

Device name drift: /dev/sdb can become /dev/sdc after a reboot if another disk is added. Always use UUIDs in /etc/fstab and scripts — never bare device paths.

Partition table not visible immediately: After writing changes with fdisk or parted, the kernel may not immediately re-read the partition table if the disk is in use. Run sudo partprobe /dev/sdb or reboot.

4K sector alignment: Older tools default to cylinder-based alignment, which causes misalignment on modern 4K-sector drives. Use parted’s percentage syntax or fdisk’s default sector alignment (2048 sectors = 1 MiB).

ext4 on large disks: For volumes larger than 16 TB, switch to xfs. The mkfs.ext4 command will warn you, but it is easy to miss.

Missing nofail on non-root disks: Without nofail, a missing secondary disk will cause the system to drop into emergency mode at boot. Always add nofail to any non-root fstab entry.

GPT on a BIOS system without a BIOS boot partition: When using GPT with GRUB on a non-UEFI system, you need a small (1 MiB) unformatted partition with type BIOS boot (code ef02 in gdisk or parted type bios_grub). Without it, GRUB cannot install its stage 2.

Troubleshooting Common Issues

mount: /mnt/data: can't read superblock — The filesystem was not created, or it was created on the wrong device. Run file -s /dev/sdb1 to check whether a filesystem exists.

mount: wrong fs type, bad option, bad superblock — Mismatch between the filesystem type in fstab and the actual type on disk. Run blkid /dev/sdb1 to verify the TYPE field and correct the fstab entry.

WARNING: Re-reading the partition table failed — The kernel could not update its view of the partition table because the disk is busy. If this happens on a disk other than the boot disk, run partprobe or reboot.

UUID changes after mkfs — Every mkfs call assigns a new UUID. If you reformat a partition and do not update /etc/fstab, the system will fail to mount it. Always run blkid after formatting and update fstab immediately.

parted: Error: Partition(s) on /dev/sdb are being used — One or more partitions on the disk are currently mounted. Unmount all of them before reclabeling or resizing.

Summary

  • Choose GPT for all new disks in 2025 — it supports 128 partitions, disks beyond 2 TB, and provides a backup partition table header.
  • Use fdisk for interactive partitioning; use parted when you need scripting, automation, or disks larger than 2 TB.
  • Always format a new partition with mkfs before mounting — a raw partition has no filesystem.
  • Use UUID (not device names like /dev/sdb1) in /etc/fstab to ensure mounts survive disk reordering.
  • Add nofail to all non-root fstab entries so a missing disk does not prevent the system from booting.
  • Verify every fstab change with mount -a before rebooting — a bad entry can make the system unbootable.
  • Align partitions to MiB boundaries (parted percentage syntax or fdisk defaults) for optimal SSD and NVMe performance.