kdave / btrfs-progs

Development of userspace BTRFS tools
GNU General Public License v2.0
530 stars 240 forks source link

mkfs.btrfs --rootdir does not properly handle sparse files #653

Open crass opened 11 months ago

crass commented 11 months ago

When calculating the minimum size of filesystem mkfs.btrfs uses st.st_size from stat. But this is not necessarily the amount of bytes the file occupies. For sparse files, it should be more like st.st_blocks * block size.

This can cause mkfs.btrfs to fail when writing to a block device with the error: ERROR: unable to zero the output file. This is because mkfs.btrfs tries to extend the length of the file to be the minimum size it (incorrectly) thinks it needs to populate the new file system. However, block devices can not be extended like files, so this write beyond the end of the device fails. This error message is cryptic or non-intuitive for the user in this case, which should have the message "ERROR: block device too small to fit all data from rootdir".

adam900710 commented 9 months ago

We can firstly disable the extend if the target file is not a block file.

Then we can address the size limits using st_blocks instead.

Thanks for the report.

adam900710 commented 9 months ago

BTW, even if we don't enlarge block file, mkfs.btrfs would still fail due to ENOSPC.

As for now, we still populate the file on btrfs by:

This means, for sparse file, the resulted file in the btrfs would not be sparse anymore, but all filled with zero.

We need to address this behavior first before using st_blocks.