lvextend runs without error, genuinely increases the logical volume’s size as requested, and yet df -h keeps showing exactly the same size as before for the filesystem mounted on it. This isn’t a silent lvextend failure: the logical volume and the filesystem it contains are two distinct layers, and LVM never resizes the second one automatically.

Two layers, two different commands

LVM manages disk space at a block level, independent of the filesystem using it: lvextend changes the logical volume’s own size (the available block space), but the filesystem formatted inside it (ext4, xfs) keeps believing it occupies the old size until a filesystem-specific command explicitly tells it about the change.

# Step 1: grows the logical volume itself,
# the available block space genuinely increases
lvextend -L +10G /dev/vg-data/lv-data

# Step 2 (mandatory, separate): informs the
# ext4 filesystem of the new available size
resize2fs /dev/vg-data/lv-data

# Step 2 for XFS: the command and its behavior
# differ from ext4, xfs_growfs takes the mount
# point, not the device
xfs_growfs /data

Why df isn’t lying

df faithfully reports the filesystem’s size as it knows itself, not the underlying logical volume’s size: after an lvextend without the corresponding resize step, df shows exactly the truth, a filesystem that simply hasn’t been informed yet of the extra available space.

# Confirms the logical volume's actual size
lvdisplay /dev/vg-data/lv-data | grep "LV Size"

# Confirms (or disproves) that the filesystem
# has actually been informed of that new size
df -h /data

Combining both steps into one command

lvextend accepts an option that automatically triggers the corresponding filesystem resize, removing the risk of forgetting the second step.

# -r automatically triggers resize2fs or xfs_growfs
# depending on the detected filesystem type
lvextend -r -L +10G /dev/vg-data/lv-data

The connection to disk space already covered

This trap is the exact mirror of the one already documented on inode exhaustion: in both cases, a tool faithfully reports a real filesystem state that doesn’t match the operator’s first intuition, available block space being just one dimension worth checking explicitly rather than assumed resolved by a single command.

Takeaway

lvextend only grows the logical volume, never the filesystem it contains: df keeps showing the old size until a dedicated command (resize2fs for ext4, xfs_growfs for XFS) explicitly informs the filesystem of the change. lvextend’s -r option combines both steps into a single command, removing the risk of forgetting the second one. This two-layer behavior mirrors the same principle already seen with inode exhaustion: disk space has several independent dimensions, each deserving an explicit check rather than an assumption.