3

Why am I seeing:

btrfs replace "ERROR: target device smaller than source device"

when I have already shrunk the source device filesystem to be smaller than the target via:

btrfs filesystem resize <devid>:<small-size> /mountpoint

3 Answers 3

14

I encountered this when trying to replace a disk with one slightly smaller. I was getting this error even after resizing the filesystem on the source drive. Since I was using whole disks, there was no option to resize the partition. The trick turned out to be to pass a devid for the source drive instead of a device path. That seemed to result in btrfs filesystem replace checking the actually filesystem size on the source device, and not the size of the device itself.

My initial state:

# btrfs fi show /mnt/storage
Label: 'Storage'  uuid: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
    Total devices 5 FS bytes used 15.25TiB
    devid    1 size 7.28TiB used 3.84TiB path /dev/sdb
    devid    2 size 7.28TiB used 3.84TiB path /dev/sdc
    devid    3 size 7.28TiB used 3.84TiB path /dev/sdd
    devid    4 size 7.28TiB used 3.84TiB path /dev/sde
    devid    5 size 7.28TiB used 3.84TiB path /dev/sdf

I wanted to replace /dev/sdf with /dev/sdg.

Attempt #1:

# btrfs replace start /dev/sdf /dev/sdg /mnt/storage
ERROR: target device smaller than source device (required 8001561124864 bytes)

Resizing the filesystem on /dev/sdf (devid 5):

# blockdev --getsize64 /dev/sdg 
8001546444800

# btrfs fi res 5:8001546444800 /mnt/storage
Resize '/mnt/storage' of '5:8001546444800'

Attempt #2:

# btrfs replace start /dev/sdf /dev/sdg /mnt/storage
ERROR: target device smaller than source device (required 8001561124864 bytes)

No change. It appears when specifying the source as a block device, replace only looks at the size of the block device when checking whether there is enough space on the destination. However, perusing the source code, I discovered that replace handles a source devid differently, and actually retrieves the correct size from the filesystem.

This led to attempt #3:

# btrfs replace start 5 /dev/sdg /mnt/storage

This formulation, combined with the preceding resize, allowed the replace operation to start successfully.

0

The error message is referring to the Linux block device sizes, not the filesystem size, so the partition containing the source filesystem will need to be shrunk to be smaller than (or the same size as) the target.

Assuming the target device is 200G, resize the source device to 199G:

btrfs filesystem resize <devid>:199g /mountpoint

Then resize the partition to also be 199GiB. I used gdisk to remove the existing source partition, then created a new one with the same start sector but entered the end sector size as +199G.

After a partprobe /dev/hdd-device to reload the new partition, the replace worked fine.

0

While the both approaches seem to work, @rkjnsn solution seems less risky since it doesn’t require overwriting partition table of a live disk. Things can get very wrong there.

2

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .