On a Linux host using LVM, you run `lvextend -L +50G /dev/vg0/data` and it reports success, yet `df -h` still shows the old size for the mounted filesystem. Why, and what do you run to make the filesystem use the new space?
answer
- two sizes, not one
- block device grew, filesystem did not
- the resize tool depends on the filesystem
- one flag on lvextend does both
basics
~20 sAn LVM logical volume and the filesystem on it are separate layers. lvextend grew only the block device, so the filesystem still records its old size. Run resize2fs (ext4) or xfs_growfs (XFS) afterwards, or pass lvextend -r to do both.
solid answer
~40 sThere are two sizes here, not one. `lvextend` allocated more physical extents to the logical volume, so the block device `/dev/vg0/data` is bigger — `lvs` and `lsblk` will show that immediately. The filesystem written on top of that device keeps its own size in its superblock, and nothing has told it the device grew, so `df` still reports the old capacity. The fix is a filesystem-level resize: `resize2fs /dev/vg0/data` for ext2/3/4, which with no size argument grows to fill the device and works while mounted, or `xfs_growfs /data` for XFS, which takes the **mount point** and requires the filesystem to be mounted. You can collapse both steps into one by adding `-r` (`--resizefs`) to `lvextend`, which hands off to `fsadm` and calls the right tool for you.
code
bash · 9 lines# grow the logical volume, then the filesystem on it
lvextend -L +50G /dev/vg0/data
resize2fs /dev/vg0/data # ext4: takes the device, works while mounted
# or let LVM call the right resizer itself
lvextend -r -L +50G /dev/vg0/data
# XFS is grown by mount point, and must be mounted
xfs_growfs /datago deeper
Know that the logical volume and the filesystem are two separate sizes, and name the second command: resize2fs for ext4, xfs_growfs for XFS. Saying 'lvextend -r does both' is a strong short answer.
Explain why the layers are independent, which tool takes a device and which takes a mount point, and that -r delegates to fsadm. Be able to show the mismatch with lvs versus df.
Show the diagnosis order — lvs, lsblk, df — so you can tell a missed filesystem resize from a block device that never grew at all. Mention that this is an online operation with no service impact.
Frame the layer separation as deliberate: a logical volume may hold a raw database device or swap, so LVM cannot resize the payload for you. Talk about making the grow path a scripted, monitored runbook rather than a manual three-command ritual.
## Two layers, two independent sizes LVM inserts a layer between the disk and the filesystem. Physical volumes (whole disks or partitions) are pooled into a volume group, the volume group is carved into logical volumes, and a filesystem is created on a logical volume. Each layer tracks its own size: - The logical volume's size is stored in LVM metadata, as a count of physical extents. - The filesystem's size is stored in its own superblock, in filesystem blocks. Growing one does not grow the other. That is the whole of the surprise: `lvextend` is a block-layer operation, and `df` is a filesystem-layer report. ## What lvextend actually did `lvextend -L +50G /dev/vg0/data` took 50 GB worth of free extents from the volume group and mapped them onto the end of the logical volume. The device-mapper table for the device is updated live, so the block device is larger the moment the command returns — no unmount, no reboot. You can confirm at the block layer: ``` lvs -o lv_name,lv_size vg0 lsblk /dev/vg0/data ``` Both show the new size while `df -h /data` still shows the old one. That discrepancy is the diagnostic: block layer big, filesystem layer small. ## Growing the filesystem The tool depends on the filesystem, and it is worth memorising which argument each one takes: ``` resize2fs /dev/vg0/data # ext2/ext3/ext4 - takes the DEVICE, online grow is supported xfs_growfs /data # XFS - takes the MOUNT POINT, must be mounted ``` With no size argument, both grow to fill whatever the underlying device now is, which is exactly what you want after an `lvextend`. Online growth is normal on both: ext4 supports online resize through a kernel ioctl, and XFS can only be grown while mounted, so there is no reason to take an outage for a grow. ## Doing both in one command `lvextend -r -L +50G /dev/vg0/data` (long form `--resizefs`) extends the logical volume and then calls `fsadm`, a helper shipped with LVM2 that detects the filesystem type and invokes the matching resize tool. `lvresize -r` behaves the same way. If `fsadm` does not recognise the filesystem it refuses, and you are left in exactly the state described in the question — a grown LV with an unchanged filesystem, which is harmless and fixable by hand. ## The -L versus -l trap `lvextend` accepts sizes two ways, and both accept absolute or relative forms: - `-L 100G` sets the size **to** 100 GB; `-L +100G` **adds** 100 GB. - `-l 100` sets the size to 100 extents; `-l +100%FREE` adds every free extent in the volume group. Typing `-L 100G` when you meant `-L +100G` on a volume that is already larger is the classic slip. `lvextend` itself will not reduce a volume — it errors out rather than shrinking — but `lvresize` will happily do what you asked, and shrinking a block device out from under a live filesystem destroys data. Prefer the explicit `+` form for growth. ## When there is nothing to extend with If the volume group has no unallocated extents, `lvextend` fails with an insufficient-free-extents error instead of succeeding. Check with `vgs`, whose `VFree` column is the free space in the group. Getting more space into the group is a separate step: adding a new physical volume with `vgextend`, or telling LVM that an existing physical volume's underlying device has grown with `pvresize`. ## Verifying the whole chain After a successful grow, all four views should agree: ``` vgs # VFree - what is left in the group lvs -o lv_name,lv_size # the logical volume size lsblk # the block device the kernel sees df -h /data # what the filesystem now offers ``` If `df` is the only one lagging, you skipped the filesystem step. If `lsblk` lags too, the block device itself never grew and the problem is below LVM — a virtual disk that was enlarged in the hypervisor but never rescanned, for instance. ## Why this design is deliberate The separation is a feature, not an oversight. A logical volume may hold something that is not a filesystem at all — a database's raw device, a swap area, an encrypted container — and LVM has no business guessing how to resize an arbitrary payload. Keeping the layers independent is what lets the same `lvextend` serve all of them, with `-r` as the convenience path for the common case.
- Do you have to unmount the filesystem to grow it after an lvextend?No, not for the common cases. ext4 supports online growth through a kernel resize ioctl, so `resize2fs` works on a mounted filesystem. XFS is stronger still — `xfs_growfs` requires the filesystem to be mounted, since it takes a mount point. Growing storage on a live service is a routine online operation; only shrinking forces an outage.
- What does the -r flag on lvextend actually invoke?It calls `fsadm`, the LVM2 helper that inspects the filesystem on the volume and dispatches to the right tool — `resize2fs` for ext2/3/4, `xfs_growfs` for XFS. It is a convenience wrapper, not a resizer itself, so if the volume holds something `fsadm` does not recognise it refuses and you resize by hand.
- You run lvextend and it fails with an insufficient-free-extents message. What is wrong?The volume group has nothing left to allocate. Check `vgs` — the `VFree` column is the group's unallocated space. You need to enlarge the group first, either by adding another physical volume with `vgextend` or, if an existing physical volume's underlying device was enlarged, by running `pvresize` on it.
saying these in an interview costs you the question
- Thinks df updates itself once the logical volume grows
- Suggests re-running mkfs to pick up the new size
- Believes growing ext4 requires unmounting the filesystem
- Passes xfs_growfs a device path instead of the mount point
- Confuses lvextend -L 50G with -L +50G