After a couple of months of using a raspberry as a home server with MiniDLNA as a media server and a headless Transmission daemon as bittorrent client that works 24/7 downloading any kind of media I want, it surprises me that I managed to not fill the storage as quick as I could have.

Adding a red mushroom to SSD increases it's size

And now it pays off that I picked ext2 (I don’t need extensive logging nor datacenter capabilities) as my file system format, since cloning and growing the partition is a pretty straightforward operation. What needs to be done is basically:

TL;DR

  1. Copy/clone the old disk to the new disk
  2. Run e2fsck(8) on the ext2/ext3/ext4 partition in the new disk (use the -f option to be safe)
  3. Rewrite/modify the partition table in the new disk; can be done with fdisk(8). DANGER: you need to pay close attention to the “Start block”, because the ext2 metadata is located there. If you overwrite it or start somewhere else, the files location will be lost and your data might be lost forever.
  4. Run resize2fs(8) on the ext2/ext3/ext4 partition in the new disk

Copy/Clone the Disk

This is done very easily with dd(1), we just specify the input file the old disk (/dev/sdb) and the new one (/dev/sdc) as output file, I also pass the block size parameter to speed up the process:

# dd if=/dev/sdb of=/dev/sdc bs=4K

The command doesn’t print anything when things are going well, but you can print the progress to the tty executing dd by sending the USR1 signal to the process (see dd(1)):

# kill -s USR1 $(pidof dd)

Run fdisk on the New Disk

Most linux distributions include an interactive implementation of fdisk(8) which is what I used and cannot write about the scriptable implementation. What you want to do is:

# fdisk /dev/sdc

Welcome to fdisk (util-linux 2.37.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


Command (m for help): p

Disk /dev/sda: 223.57 GiB, 240057409536 bytes, 468862128 sectors
Disk model: ADATA SU630
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: 0xbe4e4347

Device     Boot   Start       End   Sectors   Size Id Type
/dev/sda1          2048   2099199   2097152   111G 83 Linux

Command (m for help):
  1. Print the existing partition table by issuing the p (print) command and check the start block
  2. Delete the existing partition (DO NOT WRITE CHANGES YET)
  3. Create a new partition with the new desired size. Make sure you use the same “Start block” used by the old/existing partition (now deleted) and the same type
  4. Write the new configuration to disk (this is what could destroy your data)

Run e2fsck on the Ext2/Ext3/Ext4 Partition

This is to check data integrity and, I think, to re-order files to continuous blocks for better performance. Let’s assume my new partitition is located on /dev/sdc1:

# e2fsck -f /dev/sdc1

Run resize2fs on the Ext2/Ext3/Ext4 Partition

This is the command that will actually grow the file system size to match the partition size, which we increased with fdisk previously:

# resize2fs /dev/sdc1

And that’s it! You can mount the partition and check the file system size with df to verify it worked. If the size is not updated, you may have not run e2fsck before resize2fs.