How to properly shrink ext4 partition

There is a number of articles in the internet that are not exactly 100% correct in how to make sure that you are correctly shrinking ext4.

Backup mbr

Before proceding, backup mbr

dd if=/dev/sda of=/tmp/mybackup.mbr bs=512 count=1

resize2fs

I am skipping this step, as my ext4 was already smaller:

/dev/sda1  *         2048 218819680 218817633 104.3G 83 Linux
/dev/sda1            57G   33G   22G  61% /

My ext4 file system is 57GB gigabytes, but my partition on disk is 104.3GB. I want to shrink my 104.3GB partition to match the requirements of the ext4 partition

e2fsck

First I am going to run e2fsck in the read-only mode:

# e2fsck -n /dev/sda1
e2fsck 1.44.5 (15-Dec-2018)
Warning!  /dev/sda1 is mounted.
Warning: skipping journal recovery because doing a read-only filesystem check.
/dev/sda1: clean, 739681/3776512 files, 10766785/15101696 blocks

# tune2fs -l /dev/sda1 | grep -i 'block size'
Block size:               4096

It tells me that my partition has 15101696 blocks, and block size is 4096. Now I need to convert it to the number of sectors

Fdisk

[email protected]:/mnt/nas/public/wspolne/Projekty# fdisk -l /dev/sda
Disk /dev/sda: 119.2 GiB, 128035676160 bytes, 250069680 sectors
Disk model: ADATA SU800
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00029e4e

Device     Boot     Start       End   Sectors   Size Id Type
/dev/sda1  *         2048 218819680 218817633 104.3G 83 Linux

This tells me that 1 sector has 512 bytes. 15101696 * 4096 / 512 = 120813568. My new partition needs to have 120813568 sectors.

I need to delete the existing partition (“d”, “1”), and create a new one (“n”, “1”), with the same starting sector (2048), and a new sector count (120813568). This will create a partition matching the ext4 partition requirements.

Disk /dev/sda: 119.2 GiB, 128035676160 bytes, 250069680 sectors
Disk model: ADATA SU800
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00029e4e

Device     Boot     Start       End   Sectors  Size Id Type
/dev/sda1            2048 120815615 120813568 57.6G 83 Linux

On the way, the partition is no longer marked as “boot” partition. To add this, type “a” and select partition “1”.

Now when I type “p” I can see correct sda1 partition.

Command (m for help): p
Disk /dev/sda: 119.2 GiB, 128035676160 bytes, 250069680 sectors
Disk model: ADATA SU800
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00029e4e

Device     Boot     Start       End   Sectors  Size Id Type
/dev/sda1  *         2048 120815615 120813568 57.6G 83 Linux

Now I can type “w” and reboot. To run a filesystem check when booting, before the reboot, add

touch /forcefsck

Watch for fsck output while initing the system.