How to Resize and Extend a Linux Partition and Filesystem

By 

•

Published on

•

14 min read

Partition and filesystem layers expanding into free space in a storage tray

You resized the disk of your cloud server from 50 GiB to 100 GiB, rebooted, and df -h still shows the old size. This is one of the most common storage tasks on Linux: the disk grew, but the partition and the filesystem on top of it did not. Each layer has to be extended separately before the space becomes usable.

This guide explains how to grow a partition and its filesystem to fill new disk space, including the extra steps needed on LVM setups, and how to shrink a partition when you have to.

Warning
Take a backup or snapshot before changing partition boundaries. Confirm the disk, partition number, filesystem type, and mount point before every write operation. The device names below are examples; replace them with the devices on your system, and never change a partition’s start position to extend it.

Quick Reference

TaskCommand
Preview growing partition 1 on /dev/sdasudo growpart --dry-run /dev/sda 1
Grow partition 1 on /dev/sdasudo growpart /dev/sda 1
Grow an ext4 filesystemsudo resize2fs /dev/sda1
Grow an XFS filesystem mounted at /sudo xfs_growfs -d /
Grow a single-device Btrfs filesystem mounted at /sudo btrfs filesystem resize max /
Grow an LVM physical volumesudo pvresize /dev/sda3
Extend an LVM volume and its ext4 or XFS filesystemsudo lvextend -r -l +100%FREE /dev/ubuntu-vg/ubuntu-lv

Use only the commands that match your layout. +100%FREE consumes all free extents in the volume group; use a fixed increase when you need to keep space for other volumes or snapshots.

Disk, Partition, and Filesystem Layers

Storage on Linux is stacked . At the bottom is the disk (/dev/sda), which holds a partition table describing one or more partitions (/dev/sda1). A plain partition contains a filesystem such as ext4 or XFS. With LVM, a physical volume supplies space to a volume group, which allocates that space to logical volumes. The filesystem sits on a logical volume.

Enlarging a virtual disk only changes the bottom layer. To use the new space you extend each layer above it, in order: partition, LVM physical volume and logical volume if present, then filesystem. If only the filesystem is smaller than its partition, growing the filesystem alone is enough. If an LVM volume group already has free extents, you can extend a logical volume without enlarging the disk or partition.

The examples cover plain partitions and ordinary LVM logical volumes. Encrypted mappings, software RAID, and LVM thin pools need additional steps; do not apply this sequence unchanged to those layouts.

Step 1: Identify the Layout

Start by looking at what you have. The lsblk command shows the disks, partitions, filesystem types, and mount points:

Terminal
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS
output
NAME    SIZE TYPE FSTYPE MOUNTPOINTS
sda     100G disk
└─sda1   50G part ext4   /

The disk sda is 100 GiB, but the partition sda1 holding the root filesystem is still 50 GiB. lsblk uses powers of 1024 for its size suffixes, so G here means GiB. We still need to check where the free space sits before growing the partition.

Next, check the filesystem type, because the grow command differs between ext4, XFS, and Btrfs:

Terminal
df -hT /
output
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/sda1      ext4   49G   41G  5.6G  88% /

In this example the root filesystem is ext4 on /dev/sda1. On a data volume, replace / with its mount point. If lsblk shows entries of type lvm, follow the LVM section , which uses partition 3 rather than partition 1.

On NVMe devices, partition names include a p: partition 1 of /dev/nvme0n1 is /dev/nvme0n1p1. Virtio disks commonly use names such as /dev/vda and /dev/vda1.

If you enlarged the disk while the VM was running and lsblk still reports the old disk size, first confirm that the hypervisor or cloud provider completed the resize. For a SCSI device that exposes a rescan file, ask the kernel to rescan it:

Terminal
echo 1 | sudo tee /sys/class/block/sda/device/rescan

This path is specific to the device driver; it is not a general NVMe or virtio rescan command. If the file does not exist, follow your platform’s rescan procedure or reboot. Run lsblk again and confirm the larger disk size before continuing.

Next, inspect the partition boundaries and free regions with parted . If it is missing, install the parted package with your package manager:

Terminal
sudo parted /dev/sda -- unit MiB print free

The Free Space region you want must begin directly after the target partition. If another partition sits between it and the new space, growpart cannot move that partition out of the way. On an enlarged GPT disk, parted may offer to repair the backup header; see Troubleshooting before accepting that repair.

Step 2: Grow the Partition

The easiest way to grow a partition is growpart, a tool built for exactly this job. It supports MBR and GPT disks and can extend a partition in use when the kernel supports updating its size. It changes the end boundary without moving the start.

On Ubuntu, Debian, and Derivatives, install it with:

Terminal
sudo apt update
sudo apt install cloud-guest-utils

On Fedora, RHEL, and Derivatives, use:

Terminal
sudo dnf install cloud-utils-growpart

growpart takes the whole disk and the partition number as separate arguments. Preview the change first:

Terminal
sudo growpart --dry-run /dev/sda 1

The preview reports the proposed change and the old and new partition tables without writing them. Check that partition 1 is the intended target and its start stays the same, then apply the change:

Terminal
sudo growpart /dev/sda 1

For partition 1 on an NVMe disk, the equivalent grow command is:

Terminal
sudo growpart /dev/nvme0n1 1

Run the command for your device, not both examples. A CHANGED message confirms that the partition table was updated. The partition grows into adjacent free space, stopping at the next partition or the last usable part of the disk. NOCHANGE means no qualifying growth was possible; it does not necessarily mean the filesystem fills the disk.

Alternative: Growing the Partition with parted

If parted is installed, you can use its resizepart command instead of growpart. Start it against the disk:

Terminal
sudo parted /dev/sda

At the prompt, inspect the layout again. If partition 1 is the last partition and free space follows it, resize its end to the last usable part of the disk:

txt
(parted) unit MiB
(parted) print free
(parted) resizepart 1 100%
(parted) print
(parted) quit

These are commands entered at the (parted) prompt, not shell commands. parted applies a resize immediately; quit does not save a staged change. If it asks about modifying an in-use partition, confirm only after checking the target and that you are extending its end. Do not use 100% when another partition follows the target.

Both tools only change the partition table. Recent versions of fdisk also provide an e resize command; check the m menu in your installed version.

Before growing the filesystem, confirm that the kernel sees the larger partition:

Terminal
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS /dev/sda

If the partition row still has its old size, try notifying the kernel with sudo partprobe /dev/sda. If that fails because the device is busy, reboot and verify with lsblk before proceeding.

Step 3: Grow the Filesystem

Run only the command for the filesystem type you found in step 1. Mounted ext4, XFS, and Btrfs filesystems can normally grow online, provided the kernel already sees the larger underlying device. LVM users should follow the next section first.

ext4

For ext4, run resize2fs against the partition device. Without a size argument it grows the filesystem to fill the partition:

Terminal
sudo resize2fs /dev/sda1

For the NVMe example, the filesystem device is /dev/nvme0n1p1, so you would use sudo resize2fs /dev/nvme0n1p1.

On mounted ext4, the output reports an online resize and the resulting block count. The tool also supports ext2 and ext3, but online resizing depends on filesystem and kernel support. If an offline check is required, unmount a data filesystem or use live media for a root filesystem. Never run e2fsck on a mounted filesystem.

XFS

XFS uses its own tool. Pass the mount point, and use -d to grow the data section to the maximum available size. The filesystem must be mounted:

Terminal
sudo xfs_growfs -d /

For a data filesystem, replace / with its mount point. If the command reports that the data size is unchanged, check the partition or logical volume size rather than rerunning it.

Btrfs

Btrfs also resizes by mount point. For a single-device filesystem, run:

Terminal
sudo btrfs filesystem resize max /

The max keyword grows the filesystem to fill the underlying device. It defaults to device ID 1. For a multi-device filesystem, find the enlarged device’s ID with sudo btrfs filesystem show /, then specify it explicitly, such as sudo btrfs filesystem resize 2:max / for device ID 2. Resizing one device does not resize every device in the filesystem.

If a grow command is missing, install its filesystem package: e2fsprogs for ext4, xfsprogs for XFS, or btrfs-progs for Btrfs.

Extending LVM Volumes

On an LVM system, identify the physical volume, volume group, and logical volume before changing anything:

Terminal
sudo pvs
sudo vgs
sudo lvs -o lv_path,vg_name,lv_size

Use the PV and LV Path values from your output rather than assuming the Ubuntu names below. VFree in the vgs output shows space the volume group can already allocate. If enough space is available there, skip the partition growth and pvresize steps.

In this example, /dev/sda3 is the physical volume. If it needs to grow and adjacent free space is available, preview and then extend partition 3:

Terminal
sudo growpart --dry-run /dev/sda 3

Check that the preview targets partition 3 and preserves its start, then apply it:

Terminal
sudo growpart /dev/sda 3

After verifying that the kernel sees the larger partition, lsblk looks like this:

Terminal
lsblk
output
NAME                      MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
sda                         8:0    0  100G  0 disk
├─sda1                      8:1    0    1M  0 part
├─sda2                      8:2    0    2G  0 part /boot
└─sda3                      8:3    0   98G  0 part
  └─ubuntu--vg-ubuntu--lv 252:0    0   48G  0 lvm  /

The partition sda3 is already about 98 GiB, but the logical volume holding the root filesystem is still 48 GiB. The physical volume and logical volume need to expose the extra space to the filesystem.

First, extend the physical volume so LVM sees the larger partition:

Terminal
sudo pvresize /dev/sda3
output
  Physical volume "/dev/sda3" changed
  1 physical volume(s) resized or updated / 0 physical volume(s) not resized

This makes the extra extents available in the volume group. Check sudo vgs again to confirm the increase in VFree. If the physical volume occupies a whole disk rather than a partition, skip growpart and give pvresize that whole-disk device instead.

For an ordinary logical volume with ext4 or XFS, extend it into the available space and grow its filesystem in the same command:

Terminal
sudo lvextend -r -l +100%FREE /dev/ubuntu-vg/ubuntu-lv

The options are:

  • -r - Resize the filesystem along with the logical volume, using the appropriate installed filesystem helper.
  • -l +100%FREE - Add all remaining free extents in the volume group to this logical volume.

If both parts succeed, you do not need a separate resize2fs or xfs_growfs run. To add 20 GiB while keeping the remaining space available, use sudo lvextend -r -L +20G /dev/ubuntu-vg/ubuntu-lv instead.

For Btrfs on a logical volume, extend the logical volume without -r, then run btrfs filesystem resize max on its mount point. The filesystem helpers used by lvextend -r do not provide a general Btrfs resize workflow.

Verifying the New Size

Whichever path you took, confirm the filesystem capacity:

Terminal
df -h /
output
Filesystem     Size  Used Avail Use% Mounted on
/dev/sda1       98G   41G   53G  44% /

For the plain ext4 example, the root filesystem now reports about 98 GiB. Its reported capacity is lower than the disk’s size because of filesystem overhead, and available space also accounts for ext4’s reserved blocks. On LVM, the Filesystem column shows the logical volume instead. For more ways to read this output, see our guide to checking disk space with df .

Shrinking a Partition

Shrinking is riskier than growing and supports fewer filesystems.

Warning
Shrinking works in the opposite order: shrink the filesystem first, then the partition. Shrinking the partition first can cut off filesystem data. Keep a backup, and stop if any check or resize command fails. This example is for an unencrypted ext4 data partition without LVM; shrinking an LVM setup also requires reducing its intervening layers in the correct order.

resize2fs can shrink ext2, ext3, and ext4 only while unmounted. For a root filesystem, boot from live media and make sure it has not automatically mounted the partition. Btrfs has its own mounted resize command. Current XFS documentation describes limited shrinking of the last allocation group, which is not a general way to shrink an arbitrary XFS filesystem. For a substantial XFS reduction, plan to back up, recreate a smaller filesystem, and restore.

For this ext4 example, assume /dev/sdb1 starts at 1MiB and is currently larger than 41 GiB. Inspect its actual start before proceeding:

Terminal
sudo parted /dev/sdb -- unit MiB print

The target filesystem size must leave enough room for the files and metadata. Stop processes using the data volume, then unmount it:

Terminal
sudo umount /dev/sdb1

Once unmounting succeeds, run a forced filesystem check :

Terminal
sudo e2fsck -f /dev/sdb1

Resolve any reported errors before continuing. Then shrink the filesystem to 40 GiB:

Terminal
sudo resize2fs /dev/sdb1 40G

Here G means GiB, or powers of 1024. Do not replace it with GB in the partition command: parted treats GB as decimal gigabytes. Also, resizepart takes an absolute disk endpoint, not a partition size.

We will leave a 1 GiB margin by making the partition 41 GiB long. With the verified start at 1MiB, its endpoint is 1 + (41 * 1024) = 41985MiB. If your partition starts elsewhere, calculate its endpoint from that actual start instead. Open parted on the disk:

Terminal
sudo parted /dev/sdb

Confirm the start again, change only the end, accept the shrink warning only after the filesystem resize succeeded, then print the result:

txt
(parted) unit MiB
(parted) print
(parted) resizepart 1 41985MiB
(parted) print
(parted) quit

Verify that the kernel sees the new 41 GiB partition. If necessary, run sudo partprobe /dev/sdb and check again:

Terminal
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS /dev/sdb

While the filesystem is still unmounted, check it again:

Terminal
sudo e2fsck -f /dev/sdb1

After a successful check, grow the filesystem to fill the new partition exactly:

Terminal
sudo resize2fs /dev/sdb1

You can now mount the filesystem at its original mount point and verify its capacity with df -h. The GNU Parted unit reference explains why explicit binary units are useful when setting exact boundaries.

Troubleshooting

growpart prints NOCHANGE
There may be no adjacent free space, another partition may block growth, or the increase may be below the tool’s threshold. Confirm that the disk itself grew, then inspect parted’s print free output. If the partition already uses the available space, check the LVM and filesystem layers instead. NOCHANGE returns exit status 1; it is not a successful resize.

df still shows the old size after growing the partition
Compare the sizes in lsblk and df -hT. If the partition is larger but the filesystem is unchanged, run its matching grow command. On LVM, verify that the physical volume and logical volume grew before resizing the filesystem.

The table changed, but lsblk still shows the old partition size
The kernel has not adopted the new boundary. Try sudo partprobe /dev/sda. If it reports that the device is busy, reboot and check the partition size before growing the next layer. Do not repeatedly rewrite the table to fix a kernel reread failure.

lsblk does not show the new disk size
Confirm that the provider completed the resize. Use the SCSI rescan from step 1 only if your device exposes that file; NVMe and virtio devices may need their platform’s procedure or a reboot.

parted warns about unusable space on a GPT disk
GPT keeps a backup header at the end of the disk. After a disk grows, the header may still be at its former end. If the warning explicitly refers to the disk’s newly available space or the backup table’s old location, confirm the disk and backup, then accept Fix. Do not accept an unrelated corruption warning as routine resize maintenance.

lvextend grew the volume but failed to resize the filesystem
Check sudo lvs -o lv_path,lv_size and df -hT before retrying. The logical volume may already have the requested capacity. Install the missing filesystem helper or resolve the reported error, then grow ext4 on the logical-volume device or XFS on its mount point. Do not repeat a relative -L +20G increase without checking, since it can allocate another 20 GiB.

growpart cannot create its temporary directory
The filesystem holding /tmp may be full. Free a little space and try again. If deleting files does not recover capacity, check our guide to fixing No space left on device .

Conclusion

Before another capacity increase, save the lsblk and df -hT output so you can see which layer changed. Keeping free extents in an LVM volume group also gives you room to extend individual volumes later without resizing the disk again.

Tags

Linuxize Weekly Newsletter

A quick weekly roundup of new tutorials, news, and tips.

About the authors

Dejan Panovski

Dejan Panovski

Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 1000+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.

View author page