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-linuxpackage installed (providesfdisk,lsblk,blkid— present by default on most distros)partedinstalled:apt install partedordnf 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
mkfsbefore mounting — a raw partition has no filesystem. - Use UUID (not device names like
/dev/sdb1) in/etc/fstabto ensure mounts survive disk reordering. - Add
nofailto all non-root fstab entries so a missing disk does not prevent the system from booting. - Verify every fstab change with
mount -abefore 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.