Last modified: June 06, 2026
This article is written in: 🇺🇸
Storage devices such as HDDs, SSDs, USB drives, and virtual disks provide raw space. Before that space can be used conveniently, it usually needs to be divided, organized, formatted, and mounted.
Linux storage can be understood in layers.
Physical disk
|
v
Partition
|
v
Filesystem
|
v
Mount point
|
v
Usable files and directories
With LVM, there are extra layers that make storage more flexible.
Physical disk or partition
|
v
Physical Volume, PV
|
v
Volume Group, VG
|
v
Logical Volume, LV
|
v
Filesystem
|
v
Mount point
The main idea is that normal partitions are relatively fixed, while LVM gives you a flexible storage pool that can be expanded, resized, and organized more easily.
A partition is a section of a storage device.
A physical disk can be divided into multiple partitions. Each partition can be used for a different purpose.
For example, a disk might contain:
/boot boot files
/ root filesystem
/home user files
swap swap space
A simple partition layout might look like this:
Disk: /dev/sda
+-------------+----------------+----------------+
| /dev/sda1 | /dev/sda2 | /dev/sda3 |
| /boot | / | /home |
| 1G | 40G | 200G |
+-------------+----------------+----------------+
Partitions are useful because they separate storage into independent regions. This can help with organization, booting, security, backups, and system recovery.
A partition table describes how a disk is divided into partitions.
The two most common partition table types are:
MBR
GPT
MBR is older. GPT is newer and more common on modern systems.
MBR stands for Master Boot Record.
MBR has an important limitation: it supports only four primary partitions.
To work around this, MBR uses extended and logical partitions.
MBR Disk
+-------------+-------------+-------------------------------+
| Primary 1 | Primary 2 | Extended Partition |
| | | +----------+ +-------------+ |
| | | | Logical | | Logical | |
| | | | Part 1 | | Part 2 | |
| | | +----------+ +-------------+ |
+-------------+-------------+-------------------------------+
The extended partition is a container. It does not directly hold a filesystem in the normal way. Instead, it contains logical partitions.
Important point:
Primary, extended, and logical partitions are mainly MBR concepts.
GPT stands for GUID Partition Table.
GPT is the modern partitioning scheme. It avoids many MBR limitations.
With GPT:
A GPT disk looks simpler conceptually:
GPT Disk
+-------------+-------------+-------------+-------------+
| Partition 1 | Partition 2 | Partition 3 | Partition 4 |
+-------------+-------------+-------------+-------------+
On modern Linux systems, GPT is usually preferred unless there is a specific compatibility reason to use MBR.
A volume is a usable storage area that can contain a filesystem.
A volume may be a simple partition, such as:
/dev/sda1
or it may be a logical volume created by LVM, such as:
/dev/vg_data/lv_home
The important difference is that a partition is tied directly to a section of one disk, while a logical volume can be created from a flexible storage pool.
A partition is a physical division of a disk.
A volume is a usable storage unit that usually contains a filesystem.
A simple partition-based setup looks like this:
Disk
|
+--> Partition
|
+--> Filesystem
|
+--> Mount point
An LVM-based setup looks like this:
Disk or partition
|
+--> Physical Volume
|
+--> Volume Group
|
+--> Logical Volume
|
+--> Filesystem
|
+--> Mount point
In everyday use, both a partition and a logical volume can be formatted and mounted.
The difference is in how flexible they are to manage.
LVM stands for Logical Volume Manager.
LVM allows Linux systems to manage storage more flexibly than traditional partitions.
With LVM, you can:
For example, instead of being locked into a fixed /home partition size, you could create a logical volume for /home and expand it later if users need more space.
LVM has three main layers:
Physical Volume, PV
Volume Group, VG
Logical Volume, LV
A physical volume is a disk or partition prepared for LVM.
A volume group is a pool of storage made from one or more physical volumes.
A logical volume is a usable storage unit created inside a volume group.
|-----------------| |-----------------| |-----------------|
| Physical Volume | | Physical Volume | | Physical Volume |
| PV: /dev/sdb | | PV: /dev/sdc | | PV: /dev/sdd |
| Size: 50G | | Size: 100G | | Size: 150G |
|-----------------| |-----------------| |-----------------|
| | |
+-----------------------+-----------------------+
|
v
|------------------------------------------------------------------|
| Volume Group: TEST |
| Total Size: 300G |
| |
| |------------------| |------------------| |
| | Logical Volume | | Logical Volume | Free Space |
| | vol_name_1 | | vol_name_2 | 30G |
| | Size: 180G | | Size: 90G | |
| |------------------| |------------------| |
| |
|------------------------------------------------------------------|
This means:
/dev/sdb, /dev/sdc, and /dev/sdd are physical volumesTESTTESTA physical volume, or PV, is a disk or partition initialized for use by LVM.
Examples:
/dev/sdb
/dev/sdc1
/dev/nvme1n1p3
A PV is not normally mounted directly. Instead, it becomes part of a volume group.
To create a physical volume:
sudo pvcreate /dev/sdb
To view physical volumes:
sudo pvs
Example output:
PV VG Fmt Attr PSize PFree
/dev/sdb TEST lvm2 a-- 50.00g 0
/dev/sdc TEST lvm2 a-- 100.00g 10.00g
/dev/sdd TEST lvm2 a-- 150.00g 20.00g
Interpretation:
| Field | Description |
| PV | Physical volume device |
| VG | Volume group the PV belongs to |
| PSize | Total size of the PV |
| PFree | Unused space on that PV |
A volume group, or VG, is a storage pool made from one or more physical volumes.
Example:
TEST
A VG combines the capacity of all physical volumes assigned to it.
To create a volume group:
sudo vgcreate TEST /dev/sdb
To add more physical volumes to an existing volume group:
sudo vgextend TEST /dev/sdc /dev/sdd
To view volume groups:
sudo vgs
Example output:
VG #PV #LV #SN Attr VSize VFree
TEST 3 2 0 wz--n- 300.00g 30.00g
Interpretation:
| Field | Description |
| #PV | Number of physical volumes in the group |
| #LV | Number of logical volumes in the group |
| VSize | Total size of the volume group |
| VFree | Unused space still available |
The VFree value is important. It tells you how much space is available for new logical volumes or for extending existing ones.
A logical volume, or LV, is the usable storage area created inside a volume group.
It behaves much like a partition. You can format it, mount it, and store files on it.
Examples:
/dev/TEST/vol_name_1
/dev/mapper/TEST-vol_name_1
Both paths usually refer to the same logical volume.
To create a logical volume:
sudo lvcreate -L 20G -n vol_name_1 TEST
This creates a 20 GB logical volume named vol_name_1 inside the volume group TEST.
To view logical volumes:
sudo lvs
Example output:
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
vol_name_1 TEST -wi-a----- 180.00g
vol_name_2 TEST -wi-a----- 90.00g
Interpretation:
| Field | Description |
| LV | Logical volume name |
| VG | Volume group name |
| LSize | Logical volume size |
| Attr | Volume attributes |
A logical volume is not ready for normal file storage until it has a filesystem.
For example, to create an ext4 filesystem:
sudo mkfs.ext4 /dev/TEST/vol_name_1
Then create a mount point:
sudo mkdir -p /mnt/mydata
Mount it:
sudo mount /dev/TEST/vol_name_1 /mnt/mydata
Check it:
df -h /mnt/mydata
Example output:
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/TEST-vol_name_1 20G 24K 19G 1% /mnt/mydata
Interpretation:
The logical volume is formatted, mounted, and usable.
Files written to /mnt/mydata are stored on the LV.
LVM names usually follow this pattern:
/dev/VOLUME_GROUP/LOGICAL_VOLUME
Example:
/dev/TEST/vol_name_1
Linux may also show the same LV under /dev/mapper:
/dev/mapper/TEST-vol_name_1
Both refer to the same logical volume.
A full LVM setup usually follows this order:
Example:
sudo pvcreate /dev/sdb /dev/sdc /dev/sdd
sudo vgcreate TEST /dev/sdb
sudo vgextend TEST /dev/sdc /dev/sdd
sudo lvcreate -L 20G -n vol_name_1 TEST
sudo lvcreate -L 12G -n vol_name_2 TEST
sudo mkfs.ext4 /dev/TEST/vol_name_1
sudo mkdir -p /mnt/vol1
sudo mount /dev/TEST/vol_name_1 /mnt/vol1
One of the biggest advantages of LVM is that logical volumes can be extended.
If the volume group has free space, you can increase an LV size.
Example:
sudo lvextend -L +10G /dev/TEST/vol_name_1
This adds 10 GB to the logical volume.
However, the filesystem also needs to be expanded.
For ext4:
sudo resize2fs /dev/TEST/vol_name_1
A more convenient method is to use -r, which resizes the filesystem automatically:
sudo lvextend -r -L +10G /dev/TEST/vol_name_1
This is often safer and simpler because it handles both steps:
extend LV
resize filesystem
Reducing a logical volume is more dangerous than extending it.
If done incorrectly, it can destroy data.
The safe order for ext4 is:
Example:
sudo umount /dev/TEST/vol_name_1
sudo e2fsck -f /dev/TEST/vol_name_1
sudo resize2fs /dev/TEST/vol_name_1 15G
sudo lvreduce -L 15G /dev/TEST/vol_name_1
sudo mount /dev/TEST/vol_name_1 /mnt/vol1
Important warning:
Do not reduce an LV before reducing the filesystem.
The filesystem must fit inside the smaller LV.
For some filesystems, such as XFS, shrinking is not supported. XFS can be grown online but not shrunk in place.
To delete a logical volume, first unmount it.
sudo umount /mnt/vol1
Then remove it:
sudo lvremove /dev/TEST/vol_name_1
LVM will ask for confirmation.
After removal, the space returns to the volume group as free space.
Check with:
sudo vgs
An LVM snapshot captures the state of a logical volume at a point in time.
Snapshots are useful for:
A snapshot does not immediately copy all data. Instead, it uses copy-on-write behavior. When data changes on the original LV, the snapshot keeps the old blocks so it can preserve the earlier state.
Original LV before snapshot
|
v
Snapshot created
|
v
Changes happen on original LV
|
v
Snapshot preserves old data blocks
Create a snapshot:
sudo lvcreate -L 1G -s -n snap_vol_name_1 /dev/TEST/vol_name_1
This creates a 1 GB snapshot named snap_vol_name_1.
View snapshots:
sudo lvs
Example output:
LV VG Attr LSize Origin Data%
snap_vol_name_1 TEST swi-a-s--- 1.00g vol_name_1 12.00
vol_name_1 TEST owi-a-s--- 20.00g
Interpretation:
snap_vol_name_1 is a snapshot of vol_name_1Data% shows how much of the snapshot space is usedData% reaches 100%, the snapshot becomes invalidTo merge a snapshot back into the original logical volume:
sudo lvconvert --merge /dev/TEST/snap_vol_name_1
The merge may happen immediately or at the next activation, depending on whether the origin volume is active.
A common safe workflow is:
Snapshots are useful, but they are not a full backup replacement. If the disk fails, snapshots on the same disk may be lost too.
/etc/fstabIf you want an LV mounted automatically at boot, add it to /etc/fstab.
Example:
/dev/TEST/vol_name_1 /mnt/vol1 ext4 defaults 0 2
A more robust option is to use a UUID.
Find the UUID:
sudo blkid /dev/TEST/vol_name_1
Example:
/dev/TEST/vol_name_1: UUID="1111-2222" TYPE="ext4"
Then use:
UUID=1111-2222 /mnt/vol1 ext4 defaults 0 2
Test /etc/fstab before rebooting:
sudo mount -a
Primary partition:
Extended partition:
Logical partition:
LVM logical volume:
Modern note:
On GPT disks, primary/extended/logical partition limits are mostly not relevant.
GPT supports many normal partitions without extended partitions.
Use normal partitions when:
Use LVM when:
A common Linux server layout might use both:
/boot normal partition
/boot/efi EFI system partition
/ LVM logical volume
/home LVM logical volume
/var LVM logical volume
| Command | Description |
pvs |
Show physical volumes |
pvdisplay |
Detailed physical volume info |
vgs |
Show volume groups |
vgdisplay |
Detailed volume group info |
lvs |
Show logical volumes |
lvdisplay |
Detailed logical volume info |
lsblk |
Show block devices and mount points |
lsblk -f |
Show filesystems and UUIDs |
df -h |
Show mounted filesystem usage |
blkid |
Show UUID and filesystem type |
Creation commands:
pvcreate /dev/sdbvgcreate TEST /dev/sdbvgextend TEST /dev/sdclvcreate -L 20G -n vol_name_1 TESTmkfs.ext4 /dev/TEST/vol_name_1mount /dev/TEST/vol_name_1 /mnt/vol1Resize commands:
lvextend -r -L +10G /dev/TEST/vol_name_1
resize2fs /dev/TEST/vol_name_1
lvreduce -L 15G /dev/TEST/vol_name_1
Snapshot commands:
lvcreate -L 1G -s -n snap_vol_name_1 /dev/TEST/vol_name_1
lvconvert --merge /dev/TEST/snap_vol_name_1
Removal commands:
umount /mnt/vol1
lvremove /dev/TEST/vol_name_1
vgremove TEST
pvremove /dev/sdb
The following lab simulates disks using regular files.
This is safer than practicing on real disks because it avoids accidentally destroying real data.
Important warning:
sudo and create block devices/dev/sda unless you intend to erase themSimulate three disks, create LVM physical volumes, combine them into one volume group, create a logical volume, format it, mount it, and verify that it works.
mkdir -p ~/lvm-lab
truncate -s 1G ~/lvm-lab/disk1.img
truncate -s 1G ~/lvm-lab/disk2.img
truncate -s 1G ~/lvm-lab/disk3.img
These files act like fake disks.
sudo losetup --find --show ~/lvm-lab/disk1.img
sudo losetup --find --show ~/lvm-lab/disk2.img
sudo losetup --find --show ~/lvm-lab/disk3.img
Example output:
/dev/loop10
/dev/loop11
/dev/loop12
Interpretation:
/dev/loop10, /dev/loop11, and /dev/loop12sudo pvcreate /dev/loop10 /dev/loop11 /dev/loop12
Example output:
Physical volume "/dev/loop10" successfully created.
Physical volume "/dev/loop11" successfully created.
Physical volume "/dev/loop12" successfully created.
Check:
sudo pvs
Example output:
PV VG Fmt Attr PSize PFree
/dev/loop10 lvm2 --- 1024.00m 1024.00m
/dev/loop11 lvm2 --- 1024.00m 1024.00m
/dev/loop12 lvm2 --- 1024.00m 1024.00m
Interpretation:
The loop devices are prepared for LVM.
They are not yet part of a volume group.
sudo vgcreate lab_vg /dev/loop10 /dev/loop11
Example output:
Volume group "lab_vg" successfully created
Check:
sudo vgs
Example output:
VG #PV #LV #SN Attr VSize VFree
lab_vg 2 0 0 wz--n- 1.99g 1.99g
Interpretation:
Two 1 GB loop disks are combined into one volume group.
The volume group has about 2 GB of usable space.
sudo lvcreate -L 1G -n data lab_vg
Example output:
Logical volume "data" created.
Check:
sudo lvs
Example output:
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
data lab_vg -wi-a----- 1.00g
Interpretation:
A 1 GB logical volume named data now exists inside lab_vg.
sudo mkfs.ext4 /dev/lab_vg/data
Example output:
Creating filesystem with 262144 4k blocks and 65536 inodes
Filesystem UUID: 12345678-abcd-1234-abcd-123456789abc
Interpretation:
The logical volume now contains an ext4 filesystem.
It can be mounted and used for files.
sudo mkdir -p /mnt/lvmlab
sudo mount /dev/lab_vg/data /mnt/lvmlab
Check:
df -h /mnt/lvmlab
Example output:
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/lab_vg-data 974M 24K 907M 1% /mnt/lvmlab
Interpretation:
The logical volume is mounted and usable.
Files placed in /mnt/lvmlab are stored on the LVM logical volume.
Simulate a common storage bottleneck: a mounted filesystem is almost full, but the volume group still has free space.
This is one of the best practical use cases for LVM.
sudo fallocate -l 850M /mnt/lvmlab/bigfile
Check usage:
df -h /mnt/lvmlab
Example output:
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/lab_vg-data 974M 851M 58M 94% /mnt/lvmlab
Interpretation:
The filesystem is almost full.
Applications writing to /mnt/lvmlab may fail soon.
sudo vgs
Example output:
VG #PV #LV #SN Attr VSize VFree
lab_vg 2 1 0 wz--n- 1.99g 1016.00m
Interpretation:
Use -r to resize the filesystem at the same time:
sudo lvextend -r -L +500M /dev/lab_vg/data
Example output:
Size of logical volume lab_vg/data changed from 1.00 GiB to 1.49 GiB.
Logical volume lab_vg/data successfully resized.
resize2fs 1.46.5
The filesystem is now 390144 blocks long.
df -h /mnt/lvmlab
Example output:
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/lab_vg-data 1.5G 851M 542M 62% /mnt/lvmlab
Interpretation:
Show what happens when the filesystem needs more space but the volume group does not have enough free space.
sudo lvextend -r -L +5G /dev/lab_vg/data
Example output:
Insufficient free space: 1280 extents needed, but only 129 available
Interpretation:
vgssudo vgs
Example output:
VG #PV #LV #SN Attr VSize VFree
lab_vg 2 1 0 wz--n- 1.99g 516.00m
Interpretation:
Only about 516 MB is free in the volume group.
A 5 GB extension is impossible without adding more storage.
Earlier, /dev/loop12 was prepared as a PV but not added to the VG.
Add it now:
sudo vgextend lab_vg /dev/loop12
Example output:
Volume group "lab_vg" successfully extended
Check:
sudo vgs
Example output:
VG #PV #LV #SN Attr VSize VFree
lab_vg 3 1 0 wz--n- 2.99g 1.51g
Interpretation:
sudo lvextend -r -L +1G /dev/lab_vg/data
Check:
df -h /mnt/lvmlab
Example output:
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/lab_vg-data 2.5G 851M 1.6G 35% /mnt/lvmlab
Interpretation:
Use LVM tools to understand the relationship between PVs, VGs, LVs, filesystems, and mount points.
lsblk
Example output:
NAME SIZE TYPE MOUNTPOINT
loop10 1G loop
└─lab_vg-data 2.5G lvm /mnt/lvmlab
loop11 1G loop
└─lab_vg-data 2.5G lvm /mnt/lvmlab
loop12 1G loop
└─lab_vg-data 2.5G lvm /mnt/lvmlab
Interpretation:
/mnt/lvmlabsudo pvs
Example output:
PV VG Fmt Attr PSize PFree
/dev/loop10 lab_vg lvm2 a-- 1020.00m 0
/dev/loop11 lab_vg lvm2 a-- 1020.00m 0
/dev/loop12 lab_vg lvm2 a-- 1020.00m 500.00m
Interpretation:
All three loop devices are physical volumes.
Some free space remains on /dev/loop12.
sudo vgs
Example output:
VG #PV #LV #SN Attr VSize VFree
lab_vg 3 1 0 wz--n- 2.99g 500.00m
Interpretation:
sudo lvs
Example output:
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
data lab_vg -wi-ao---- 2.50g
Interpretation:
o attribute indicates it is open, meaning it is active and mounted or in useCreate a snapshot, make a risky change, and understand how the snapshot protects the earlier state.
echo "original version" | sudo tee /mnt/lvmlab/example.txt
cat /mnt/lvmlab/example.txt
Example output:
original version
sudo lvcreate -L 200M -s -n data_snap /dev/lab_vg/data
Example output:
Logical volume "data_snap" created.
Check:
sudo lvs
Example output:
LV VG Attr LSize Origin Data%
data lab_vg owi-aos--- 2.50g
data_snap lab_vg swi-a-s--- 200.00m data 0.01
Interpretation:
data_snap is a snapshot of dataecho "bad change" | sudo tee /mnt/lvmlab/example.txt
cat /mnt/lvmlab/example.txt
Example output:
bad change
sudo lvs
Example output:
LV VG Attr LSize Origin Data%
data lab_vg owi-aos--- 2.50g
data_snap lab_vg swi-a-s--- 200.00m data 1.25
Interpretation:
Data% reaches 100%, the snapshot becomes invalidUnmount the filesystem first:
cd ~
sudo umount /mnt/lvmlab
Merge the snapshot:
sudo lvconvert --merge /dev/lab_vg/data_snap
Example output:
Merging of volume lab_vg/data_snap started.
lab_vg/data: Merged: 100.00%
Reactivate if needed:
sudo lvchange -ay /dev/lab_vg/data
Mount again:
sudo mount /dev/lab_vg/data /mnt/lvmlab
cat /mnt/lvmlab/example.txt
Expected output:
original version
Interpretation:
Show why snapshot size matters.
Snapshots need enough space to store changed blocks. If too much changes after the snapshot is created, the snapshot can fill up and become unusable.
sudo lvcreate -L 50M -s -n small_snap /dev/lab_vg/data
sudo fallocate -l 200M /mnt/lvmlab/change-after-snapshot.bin
sudo lvs
Example output:
LV VG Attr LSize Origin Data%
data lab_vg owi-aos--- 2.50g
small_snap lab_vg swi-a-s--- 50.00m data 100.00
Interpretation:
Remove the test LVM setup safely.
cd ~
sudo umount /mnt/lvmlab
sudo lvs
sudo lvremove /dev/lab_vg/small_snap
Only remove snapshots that exist.
sudo lvremove /dev/lab_vg/data
Example output:
Do you really want to remove active logical volume lab_vg/data? [y/n]: y
Logical volume "data" successfully removed.
sudo vgremove lab_vg
sudo pvremove /dev/loop10 /dev/loop11 /dev/loop12
sudo losetup -d /dev/loop10
sudo losetup -d /dev/loop11
sudo losetup -d /dev/loop12
rm -rf ~/lvm-lab
sudo rmdir /mnt/lvmlab
Check:
lsblk
Interpretation:
The test loop devices, LVM objects, mount point, and files have been removed.
The lab environment is cleaned up.
Symptoms:
applications cannot write files
df -h shows 100% usage
"No space left on device"
Check:
df -h
sudo vgs
sudo lvs
Interpretation:
df is full but VFree exists in vgs, extend the LVdf is full and VFree is 0, add storage or delete/move dataFix if VG has free space:
sudo lvextend -r -L +10G /dev/VG_NAME/LV_NAME
Symptoms:
lvextend fails
error mentions insufficient free extents
vgs shows VFree as 0
Check:
sudo vgs
sudo pvs
Fix:
sudo pvcreate /dev/newdisk
sudo vgextend VG_NAME /dev/newdisk
sudo lvextend -r -L +10G /dev/VG_NAME/LV_NAME
Check:
sudo lvs
lsblk
findmnt
If the LV exists but is not mounted, mount it:
sudo mkdir -p /mnt/data
sudo mount /dev/VG_NAME/LV_NAME /mnt/data
Sometimes LVM volumes exist but are inactive.
Check:
sudo lvs
Activate all volume groups:
sudo vgchange -ay
Then check again:
lsblk
Check:
sudo lvs
If snapshot Data% is near 100%, it is at risk.
Fix options:
Remove snapshot:
sudo lvremove /dev/VG_NAME/SNAPSHOT_NAME
lvextend -r when possibledf -h, lvs, vgs, and pvs before making changespvcreate on a disk containing data you want to keep/etc/fstab changes with mount -a before rebootinglvdisplay, vgdisplay, and pvdisplay, and explain the key information each command provides.pvmove command. Explain why this might be necessary, such as for hardware maintenance or upgrading storage, and outline the steps to ensure data remains accessible throughout the move.