DevOps & Workflow10 min read

    Using fdisk to manage partitions on Linux

    By AmirReliability & Network Engineering
    Share

    fdisk is the partition editor that ships in every distribution's base image. It is the tool you reach for when you have attached a new disk to a server, expanded a cloud volume, or are preparing a fresh drive for a filesystem. On modern util-linux (2.23+) it understands both MBR (legacy DOS) and GPT partition tables, so the historical advice "use gdisk for GPT" is no longer strictly necessary — though gdisk and parted are still useful for specific tasks.

    This guide covers the everyday workflow: listing what is on a disk, creating and deleting partitions, writing the table, and creating a filesystem on the result. It also points out the operations where fdisk is not the right tool, and what to use instead.

    Before you start. Partitioning is destructive when you get it wrong. Always confirm the device name (/dev/sdb, not /dev/sda), and never operate on a disk that is currently mounted or hosting a running system unless you mean to. A misplaced w (write) at the fdisk prompt is, in practice, irreversible without backups.


    What fdisk is (and isn't)

    • fdisk is an interactive partition table editor. It edits the table — it does not format filesystems, mount, or resize partitions in place.
    • It speaks both MBR (max 2 TiB, max 4 primary partitions) and GPT (multi-PB, up to 128 partitions by default).
    • It does not resize a partition while keeping the filesystem intact. For grow/shrink-in-place use growpart + resize2fs / xfs_growfs, or parted resizepart.
    • It is not LVM-aware — for LVM volumes you use pvcreate, vgextend, lvcreate, etc.
    • It cannot operate on a mounted partition's geometry. Unmount first, or work on a different disk.

    If you need to grow the filesystem inside an existing partition (the common cloud case after enlarging the volume), see the "Growing a partition online" section below — that path uses growpart, not fdisk re-creation.


    Identifying the disk

    Before touching anything, list the block devices and confirm the target:

    lsblk -f
    

    Sample output:

    NAME   FSTYPE LABEL UUID                                 MOUNTPOINTS
    sda
    ├─sda1 ext4         5b2a…                                /
    └─sda2 swap         9c1f…                                [SWAP]
    sdb
    

    Here /dev/sdb is unpartitioned and a safe target. Other useful inventories:

    sudo fdisk -l               # list all disks and their partition tables
    sudo fdisk -l /dev/sdb      # just that disk
    sudo blkid                  # UUIDs + filesystem types
    sudo parted -l              # parted's view (also shows partition table type)
    

    fdisk -l is read-only — running it never modifies anything.


    Opening a disk for editing

    sudo fdisk /dev/sdb
    

    You drop into an interactive prompt:

    Welcome to fdisk (util-linux 2.39.3).
    Changes will remain in memory only, until you decide to write them.
    Be careful before using the write command.
    
    Command (m for help):
    

    The two most important things to know about this prompt:

    1. Changes live in memory. Nothing is written to the disk until you type w. If you typed something stupid, type q to quit and discard.
    2. Type m for help. It prints the full command list — you do not need to memorise it.

    Common in-prompt commands

    Key Action
    m Print help
    p Print the current (in-memory) partition table
    n New partition
    d Delete a partition
    t Change partition type / GUID
    l List known partition type codes
    g Create an empty GPT table
    o Create an empty MBR/DOS table
    a Toggle the bootable flag (MBR only)
    i Print info about a partition
    v Verify the partition table
    w Write changes to disk and exit
    q Quit without writing

    Creating a partition table

    If the disk is brand new, create a partition table first.

    GPT (recommended for any disk > 2 TiB and for modern systems):

    Command (m for help): g
    Created a new GPT disklabel (GUID: ...).
    

    MBR/DOS (legacy BIOS boot disks, USB sticks for old systems):

    Command (m for help): o
    Created a new DOS disklabel with disk identifier ...
    

    If the disk already has a table you want to keep, skip this step — adding partitions does not require recreating the label.


    Creating a new partition

    Command (m for help): n
    Partition number (1-128, default 1):           ← press Enter
    First sector (2048-..., default 2048):         ← press Enter (aligned start)
    Last sector, +/-sectors or +/-SIZE{K,M,G,T,P} (default ...): +50G
    

    Hit Enter on the defaults for "first sector" and use a +SIZE value for the last sector — this is the safe, aligned, human-readable form. +50G makes a 50 GiB partition; leave it empty to use the rest of the disk.

    After creation:

    Command (m for help): p
    

    …will show the new partition in the table.

    Set the partition type

    By default, GPT partitions are typed as Linux filesystem (GUID 0FC63DAF-…). You usually don't need to change this. If you want a swap partition, an EFI System Partition, or RAID member:

    Command (m for help): t
    Partition number (1, default 1): 1
    Partition type or alias (type L to list all): swap        # or "uefi", "lvm", "raid"
    

    On MBR the type is a single byte: 82 = swap, 83 = Linux, 8e = LVM. l lists all codes.


    Writing the changes

    When the table looks right (p to confirm):

    Command (m for help): w
    The partition table has been altered.
    Calling ioctl() to re-read partition table.
    Syncing disks.
    

    If the disk is in use, you may see Re-reading the partition table failed: Device or resource busy — in that case run sudo partprobe /dev/sdb (or sudo udevadm settle) to nudge the kernel.


    Creating a filesystem on the new partition

    fdisk only edits the table. To actually use the partition, format it:

    sudo mkfs.ext4 -L data /dev/sdb1        # ext4 with label "data"
    # or
    sudo mkfs.xfs -L data /dev/sdb1         # xfs (no shrink, but excellent for large volumes)
    

    Mount it:

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

    Persist across reboots via /etc/fstab — always reference by UUID= (not /dev/sdb1, which can re-enumerate):

    sudo blkid /dev/sdb1
    # /dev/sdb1: UUID="5b2a…" TYPE="ext4" LABEL="data"
    

    Append a line to /etc/fstab:

    UUID=5b2a…  /mnt/data  ext4  defaults,noatime  0 2
    

    Validate the fstab entry without rebooting:

    sudo mount -a
    findmnt /mnt/data
    

    A typo in /etc/fstab can prevent the next boot — mount -a is the cheap insurance.


    Deleting a partition

    Command (m for help): d
    Partition number (1-3, default 3): 2
    Partition 2 has been deleted.
    Command (m for help): w
    

    This removes the partition's entry from the table. The data on the underlying sectors is untouched until something writes over it, but treat the partition as gone — you should not rely on recovery.

    Before deleting, unmount the partition and disable any swap that references it:

    sudo umount /dev/sdb2
    sudo swapoff /dev/sdb2     # if it was a swap partition
    

    Listing without entering the prompt

    fdisk accepts batch flags for read-only or scripted use:

    # Print one disk's table
    sudo fdisk -l /dev/sda
    
    # Print all detected disks
    sudo fdisk -l
    
    # Print only the partition type for scripts
    sudo fdisk -l /dev/sdb | awk '/^\/dev\//{print $1, $NF}'
    

    For scripted edits — non-interactive partitioning from configuration management — use sfdisk instead of fdisk. sfdisk reads the partition layout from stdin:

    sudo sfdisk /dev/sdb <<'EOF'
    label: gpt
    unit: sectors
    ,50G,L
    ,,L
    EOF
    

    That creates a 50 GiB Linux partition and a second one using the rest of the disk, with no prompts.


    Growing a partition online (cloud / virtualization)

    A frequent task is: "the cloud console expanded my volume from 100 GiB to 200 GiB — how do I use the extra space?" fdisk can do this by deleting and recreating the partition at the same start sector with a larger end, but that is fiddly and error-prone. The modern path is:

    sudo growpart /dev/sda 1          # grow partition 1 of /dev/sda to fill the disk
    sudo resize2fs /dev/sda1          # ext4 — grow the filesystem
    # or, for xfs:
    sudo xfs_growfs /mnt/data
    

    growpart (in cloud-guest-utils on Debian/Ubuntu, cloud-utils-growpart on RHEL-family) handles the table rewrite safely, even on a mounted root partition.

    If you truly want to use fdisk for this: d the partition, n it back with the same number and same first sector but a larger last sector, then w. Do not change the start sector. After writing, partprobe and resize the filesystem as above.


    When fdisk is the wrong tool

    • Resizing in place (without delete+recreate) — use parted resizepart or growpart + the filesystem's resize tool.
    • Scripted/non-interactive partitioning — use sfdisk.
    • A GPT disk where you want fine-grained type GUIDs or alignment controlgdisk is the GPT specialist and is more comfortable here.
    • LVM volumesfdisk does not see logical volumes. Use pvcreate, vgcreate, lvcreate.
    • Software RAID members — possible with fdisk but conventionally done by passing whole disks (/dev/sdb, not /dev/sdb1) to mdadm.
    • Encrypted volumes (LUKS) — partition first with fdisk, then cryptsetup luksFormat on top.

    Troubleshooting

    • Device or resource busy after w. The kernel could not re-read the table because something (a mount, an LVM PV, an active swap) is using a partition. Identify with lsof /dev/sdb* and fuser -m /dev/sdb*, unmount, and run sudo partprobe /dev/sdb.
    • New partition does not appear under /dev. Run sudo partprobe or sudo udevadm settle. If still missing, check dmesg | tail for I/O errors.
    • /etc/fstab typo locks the boot. Drop into single-user/rescue mode, mount root read-write (mount -o remount,rw /), edit /etc/fstab, reboot.
    • fdisk complains the table is GPT but you typed o (DOS). That's expected — o replaces the table. If you didn't mean to, quit with q (without w) and start over.
    • Partition is the right size but the filesystem still reads the old size. You forgot the resize2fs / xfs_growfs step. The partition is the container; the filesystem inside is a separate resize.

    Operational notes

    • Always confirm the device name before opening it. lsblk first. A fdisk /dev/sda on a production root disk is the classic foot-gun.
    • Snapshot or back up before destructive changes. Especially on cloud volumes — a 30-second snapshot is much cheaper than a restore from backup.
    • Prefer GPT. Unless you are booting a legacy BIOS system that explicitly needs MBR, GPT is the default in 2026.
    • Align to 1 MiB. fdisk does this automatically (first sector defaults to 2048 = 1 MiB) — accept the default unless you know why you want a different alignment.
    • Reference partitions by UUID in /etc/fstab. Kernel device names (/dev/sdb1) are not stable across reboots if disks are added/removed.

    Summary

    For the day-to-day "add a new disk, give it a partition, mount it" workflow, the recipe is short:

    1. lsblk -f — find the unused device.
    2. sudo fdisk /dev/sdXg (GPT) → n (new partition) → w (write).
    3. sudo mkfs.ext4 /dev/sdX1 — make a filesystem.
    4. sudo blkid — grab the UUID.
    5. Add a UUID=… /mnt/path ext4 defaults,noatime 0 2 line to /etc/fstab.
    6. sudo mount -a — verify the entry parses before rebooting.

    For anything more elaborate — scripted layouts, in-place resize, LVM, encrypted volumes — fdisk is one tool in a larger toolbox. Knowing where it ends is half the value of knowing how to use it.