I have a hard disk with a single btrfs partition (sdc1):
# lsblk
[...]
sdc 8:32 0 465.8G 0 disk
└─sdc1 8:33 0 465.8G 0 part /mnt/exthd
This partition is currently completely full:
# btrfs fi show /dev/sdc1
Label: none uuid: 3130b777-c72d-4375-a344-43571afc3e92
Total devices 1 FS bytes used 448.74GiB
devid 1 size 465.76GiB used 465.76GiB path /dev/sdc1
# btrfs fi df /mnt/exthd
Data, single: total=463.73GiB, used=448.22GiB
System, DUP: total=8.00MiB, used=80.00KiB
Metadata, DUP: total=1.01GiB, used=533.98MiB
GlobalReserve, single: total=498.27MiB, used=0.00B
All the partition’s space is currently allocated to one single image file:
# ls -l /mnt/exthd
total 514224320
-rw-r--r-- 1 root root 526676328448 Aug 16 2024 backup.img
Note: I’m using transparent zstd compression. That’s why the size of the file (> 490GiB) is even larger than would theoretically fit on the disk.
backup.img is an image of a hard disk that is currently failing, created using ddrescue. I would like to let ddrescue continue working on “as much” of this partially completed image file “as possible” because I don’t know how long the failing hard disk will last – so maybe what I have already successfully rescued might soon be gone for good. However, with the btrfs partition being in this full state, ddrescue always exits with a “No space left on device” error message.
I’ve therefore decided to process the hard disk in two parts: One part should cover as much as I have already rescued (so around 400-450 GiB of the existing backup.img) and the other part should cover the rest. (So something like ddrescue --size=400G /dev/failinghd /mnt/exthd1/part1.img and ddrescue --input-position=400G /dev/failinghd /mnt/exthd2/part2.img)
To get the file & partition back into a state that ddrescue can work with without erroring out, I decided to truncate 10-30 GiB of the end of the file. This means that I accept the risk of possibly truncating data on sectors that I could never recover, but at least I could still continue working with the most of the file as-is. So I tried running:
# truncate -s 448G backup.img
truncate: failed to truncate 'backup.img' at 481036337152 bytes: No space left on device
And then also:
# truncate -s 400G backup.img
truncate: failed to truncate 'backup.img' at 429496729600 bytes: No space left on device
But as you can see: I’m still getting the “No space left on device” error messages.
I’ve also tried balancing without success, again because of no space being left:
# btrfs balance start /mnt/exthd -dlimit=3
ERROR: error during balancing '/mnt/exthd': No space left on device
This leads me to my question: What’s my best option for enabling myself to continue working with as much of the file that ddrescue was able to produce so far?
I’ve been thinking about the following options:
truncate-ing the file (as described above), which does not seem to work- (temporarily) adding another device to the
btrfsfilesystem (e.g. a USB stick), thentruncate-ing the file, then removing the device from the filesystem again (in the hope that I will have truncated the image file enough to have it fit fully onto the “actual” backup hard drive again)
Are there other/better options that I should look into? How do they compare?
And before I forget: I’ve also found the btrfs FAQ article “Help! Btrfs claims I’m out of space, but it looks like I should have lots left!” – but it only provides guidance how to diagnose the “No space left on device” message, but no guidance on how to address it.