Others have listed tools that could be used to answer your question, but I wanted to produce an actual working implementation that you could use. So, I wrote a bash script to do exactly what you are asking: reporting how much free space is at the end of the LV not yet absorbed by the FS (such as happens when someone forgets to grow the FS itself).
I should note that since determining the size of the filesystem is dependent on that filesystem's tools, you have to personalize it for which filesystems you are using for your LVM disks. I personally use both XFS and EXT4, so the script below implements both of them. Specifically, I had to use tune2fs
for EXT4 and xfs_info
for XFS.
lvfree.sh
#!/bin/bash
# Header
printf '%-20s %-7s %8s %8s %8s\n' Mountpoint FS_Type LV_Size FS_Size LV_Free
lsblk -nlbo TYPE,FSTYPE,MOUNTPOINT,PATH,SIZE | grep -E '^lvm +(ext4|xfs)' | while read TYPE FSTYPE MOUNTPOINT PAATH SIZE; do
if [[ $FSTYPE == 'ext4' ]] ; then
FSSIZE=$(tune2fs -l $PAATH | grep -E '(Block count|Block size)' | awk 'BEGIN{x=1}{x=x*$NF}END{print x}')
elif [[ $FSTYPE == 'xfs' ]] ; then
FSSIZE=$(xfs_info $MOUNTPOINT | grep ^data | /bin/tr = ' ' | awk '{print $3*$5}')
fi
LVFREE=$((SIZE - FSSIZE))
printf '%-20s %-7s %8d %8d %8d\n' $MOUNTPOINT $FSTYPE $((SIZE/1024/1024)) $((FSSIZE/1024/1024)) $((LVFREE/1024/1024))
done
Testing it out
First, I extend a couple of my LVs, but forget to extend the FS
[root@xps joshua]# lvextend -L +1G /dev/vg1/home
Size of logical volume vg1/home changed from 90.00 GiB (23040 extents) to 91.00 GiB (23296 extents).
Logical volume vg1/home successfully resized.
[root@xps ~]# lvextend -L +256M /dev/vg1/usr
Size of logical volume vg1/usr changed from 25.00 GiB (6400 extents) to 25.25 GiB (6464 extents).
Logical volume vg1/usr successfully resized.
Now I run the script and see the free space in the LV
[root@xps ~]# ./lvfree.sh
Mountpoint FS_Type LV_Size FS_Size LV_Free
/ ext4 5120 5120 0
/var ext4 24576 24576 0
/var/log ext4 20480 20480 0
/usr ext4 25856 25600 256
/home xfs 93184 92160 1024
/tmp ext4 10240 10240 0
/opt ext4 5120 5120 0
Now, I remember to grow the XFS and EXT4 filesystems:
[root@xps ~]# xfs_growfs /home
meta-data=/dev/mapper/vg1-home isize=256 agcount=8, agsize=3276800 blks
= sectsz=512 attr=2, projid32bit=1
= crc=0 finobt=0, sparse=0, rmapbt=0
= reflink=0
data = bsize=4096 blocks=23592960, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=65536 ascii-ci=0, ftype=0
log =internal log bsize=4096 blocks=6400, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
data blocks changed from 23592960 to 23855104
[root@xps ~]# resize2fs /dev/mapper/vg1-usr
resize2fs 1.45.3 (14-Jul-2019)
Filesystem at /dev/mapper/vg1-usr is mounted on /usr; on-line resizing required
old_desc_blocks = 2, new_desc_blocks = 2
The filesystem on /dev/mapper/vg1-usr is now 6619136 (4k) blocks long.
And finally, I run my new script to see that the new space has been incorporated into the filesystems
[root@xps ~]# ./lvfree.sh
Mountpoint FS_Type LV_Size FS_Size LV_Free
/ ext4 5120 5120 0
/var ext4 24576 24576 0
/var/log ext4 20480 20480 0
/usr ext4 25856 25856 0
/home xfs 93184 93184 0
/tmp ext4 10240 10240 0
/opt ext4 5120 5120 0
Footnote: PAATH in my script is not a typo. I had to not use the variable name PATH since it is has a reserved meaning in shell scripting.
resize2fs
just as an example. I guess calculating the unused space is independent from the file system type, since it gets done on a lower level.