btrfs
btrfs copied to clipboard
Growing Btrfs volumes using Windows shell extension results in unmountable device on Linux
After resizing my disk, I found out Windows couldn't resize the partition from Disk Management and proceeded to resize it using gdisk. Then I used the resize tool in the Device button from the shell extension and put the slider to the max. The device appeared as resized.
Later on, I went to Linux to diagnose another issue and found out it is not longer mountable.
[3950554.191767] BTRFS: device label Win10Btrfs devid 1 transid 36158 /dev/dm-62 scanned by systemd-udevd (3149467)
[3950555.046406] BTRFS: device label Win10Btrfs devid 2 transid 36158 /dev/dm-63 scanned by systemd-udevd (3149467)
[3950593.533092] BTRFS info (device dm-62): disk space caching is enabled
[3950593.533100] BTRFS info (device dm-62): has skinny extents
[3950593.536509] BTRFS error (device dm-62): dev extent devid 1 physical offset 450969468928 len 1073741824 is beyond device boundary 450969468928
[3950593.537833] BTRFS error (device dm-62): failed to verify dev extents against chunks: -117
[3950593.580871] BTRFS error (device dm-62): open_ctree failed
Things I've tried:
- Using
btrfsck --repair
does not fix the problem. - Using
btrfs rescue fix-device-size
doesn't fix the problem. - Growing (doubling) the device size does not allow mounting nor change the error message.
- Reducing the device size from Windows shell extension back to original size only changes the second offset in the error message.
Grow:
[3950631.244345] dm-35: detected capacity change from 880803840 to 882900992
[3950632.263262] dm-34: detected capacity change from 880803840 to 882900992
[3950706.773671] BTRFS error (device dm-63): dev extent devid 1 physical offset 450969468928 len 1073741824 is beyond device boundary 450969468928
[3950706.776862] BTRFS error (device dm-63): failed to verify dev extents against chunks: -117
[3950706.817917] BTRFS error (device dm-63): open_ctree failed
[3950751.438241] BTRFS info (device dm-63): disk space caching is enabled
[3950751.438244] BTRFS info (device dm-63): has skinny extents
Reduce size in shell extension:
[3951177.006376] BTRFS error (device dm-63): dev extent devid 1 physical offset 450969468928 len 1073741824 is beyond device boundary 444732538880
[3951177.006419] BTRFS error (device dm-63): failed to verify dev extents against chunks: -117
[3951177.006806] BTRFS error (device dm-63): open_ctree failed
Double device size:
[3951513.343753] dm-35: detected capacity change from 882900992 to 2147483648
[3951514.647821] dm-34: detected capacity change from 882900992 to 2147483648
[3951531.134647] BTRFS info (device dm-63): disk space caching is enabled
[3951531.134650] BTRFS info (device dm-63): has skinny extents
[3951531.136821] BTRFS error (device dm-63): dev extent devid 1 physical offset 450969468928 len 1073741824 is beyond device boundary 444732538880
[3951531.139553] BTRFS error (device dm-63): failed to verify dev extents against chunks: -117
[3951531.181466] BTRFS error (device dm-63): open_ctree failed
I think you need to look into what exactly you have Device Mapper doing on Linux. It's doing something or other, whereas on Windows you're presumably working off the raw partition.
After resizing my disk, I found out Windows couldn't resize the partition from Disk Management and proceeded to resize it using gdisk. Then I used the resize tool in the Device button from the shell extension and put the slider to the max.
This wouldn't help - if you want to shrink a partition, you need to resize the FS to less than the new value before you use gdisk
.
This wouldn't help - if you want to shrink a partition, you need to resize the FS to less than the new value before you use gdisk.
I did resize it to 414 GB using the shell extension since it still mounts fine using WinBtrfs.
Here is the output of me trying to mount it (a snapshot of it this time since) in Linux with all the steps.
┤16:17:33│0│root@p4:~
#lvcreate -s -L 10G -n win10btrfs1snap vgP4/win10btrfs1
Logical volume "win10btrfs1snap" created.
┤16:17:48│0│root@p4:~
#lvcreate -s -L 10G -n win10btrfs2snap vgP4/win10btrfs2
Logical volume "win10btrfs2snap" created.
┤16:17:52│0│root@p4:~
#kpartx -a /dev/vgP4/win10btrfs1snap
┤16:18:01│0│root@p4:~
#kpartx -a /dev/vgP4/win10btrfs2snap
┤16:18:03│0│root@p4:~
#btrfs device scan
Scanning for Btrfs filesystems
┤16:18:11│0│root@p4:~
#btrfs fi show | grep -C 3 win10btrfs1snap
Label: 'Win10Btrfs' uuid: 2fe7c548-e831-479b-9082-7f16de101eaa
Total devices 2 FS bytes used 649.82GiB
devid 1 size 414.19GiB used 329.01GiB path /dev/mapper/vgP4-win10btrfs1snap1
devid 2 size 413.05GiB used 329.01GiB path /dev/mapper/vgP4-win10btrfs2snap1
┤16:18:24│0│root@p4:~
#dmsetup table|grep win10btrfs1snap
vgP4-win10btrfs1snap1: 0 882898911 linear 253:107 2048
vgP4-win10btrfs1snap: 0 882900992 snapshot 253:86 253:91 P 8
vgP4-win10btrfs1snap-cow: 0 20971520 linear 8:4 3793750016
┤16:18:42│0│root@p4:~
#dmsetup table|grep win10btrfs2snap
vgP4-win10btrfs2snap-cow: 0 20971520 linear 8:4 3814721536
vgP4-win10btrfs2snap1: 0 882898911 linear 253:110 2048
vgP4-win10btrfs2snap: 0 882900992 snapshot 253:108 253:109 P 8
┤16:18:49│0│root@p4:~
#blkid /dev/mapper/vgP4-win10btrfs1snap1 /dev/mapper/vgP4-win10btrfs2snap1
/dev/mapper/vgP4-win10btrfs1snap1: LABEL="Win10Btrfs" UUID="2fe7c548-e831-479b-9082-7f16de101eaa" UUID_SUB="ce590a11-29a1-4f16-9477-a29834ebf844" BLOCK_SIZE="4096" TYPE="btrfs" PARTLABEL="Microsoft basic data" PARTUUID="80a35f0f-1ea9-4ae2-8066-4418d3e9bd1d"
/dev/mapper/vgP4-win10btrfs2snap1: LABEL="Win10Btrfs" UUID="2fe7c548-e831-479b-9082-7f16de101eaa" UUID_SUB="4f4eb916-7b56-4b18-b6f8-d02601c70ef8" BLOCK_SIZE="4096" TYPE="btrfs" PARTLABEL="Microsoft basic data" PARTUUID="2cd45950-d962-4335-90e1-2fe565aa4843"
┤16:19:00│0│root@p4:~
#lsblk /dev/mapper/vgP4-win10btrfs*snap1
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vgP4-win10btrfs1snap1 253:111 0 421G 0 part
vgP4-win10btrfs2snap1 253:112 0 421G 0 part
┤16:19:11│0│root@p4:~
#mount /dev/mapper/vgP4-win10btrfs1snap1 /mnt/custom
mount: /mnt/custom: wrong fs type, bad option, bad superblock on /dev/mapper/vgP4-win10btrfs1snap1, missing codepage or helper program, or other error.
┤16:19:27│32│root@p4:~
#dmesg|tail -n 5
[3953097.590552] BTRFS info (device dm-111): disk space caching is enabled
[3953097.590556] BTRFS info (device dm-111): has skinny extents
[3953097.596307] BTRFS error (device dm-111): dev extent devid 1 physical offset 450969468928 len 1073741824 is beyond device boundary 444732538880
[3953097.597319] BTRFS error (device dm-111): failed to verify dev extents against chunks: -117
[3953097.598771] BTRFS error (device dm-111): open_ctree failed
I forgot to mention the reason why it is in LVM is because vgP4/win10btrfs1
and vgP4/win10btrfs2
are usually the 2 devices mounted in my Windows 10 VM. So in the case of the snapshot, vgP4-win10btrfs1snap
is the raw device, vgP4-win10btrfs1snap1
is the GPT partition exposed by kpartx
.
lsblk /dev/mapper/vgP4-win10btrfs*snap*
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vgP4-win10btrfs1snap 253:107 0 421G 0 lvm
└─vgP4-win10btrfs1snap1 253:111 0 421G 0 part
vgP4-win10btrfs2snap 253:110 0 421G 0 lvm
└─vgP4-win10btrfs2snap1 253:112 0 421G 0 part
Edit: added formatting.
Since I need to get this volume up and running by Monday morning, I'll just copy everything over and keep this one aside.
I tried using the Send subvolume feature, however I've had a CRC error while exporting the first one. Furthermore, there's no way to stream it to btrfs receive so I went with a new volume + TeraCopy. It has copied the whole subvolume which had CRC error, so that's a topic for another issue. There might also be corruption from the resize issue too thus why I mention it.
I double-checked and now that I took a bit of time to read the code, it seems there's something wrong with the resize feature on WinBtrfs. Linux Btrfs code explicitely safeguards itself from operating a volume that has extents beyond the end of device.
static int verify_one_dev_extent(struct btrfs_fs_info *fs_info,
u64 chunk_offset, u64 devid,
u64 physical_offset, u64 physical_len)
{
...
if (physical_offset + physical_len > dev->disk_total_bytes) {
btrfs_err(fs_info,
"dev extent devid %llu physical offset %llu len %llu is beyond device boundary %llu",
devid, physical_offset, physical_len,
dev->disk_total_bytes);
ret = -EUCLEAN;
goto out;
}
...
}
It also explains why I can't mount it even if I grow the underlying device, dev
is a Btrfs device, not a physical device, it checks for the end of device written in the system block. So either the WinBtrfs resize did not move all the extents or it did not update a reference somewhere and doesn't safeguard itself from working out of bound, which is probably what happened when all my writes after the resize ended up corrupt.
Closing old issues
@maharmstone, this seems quite a critical issue for just closing like that. It results in an unsuable Btrfs volume on Linux and trying to fix it using btrfsck result in an unwritable volume. Might even be better to not allow growing the volume on Windows for the time being.
There is a check to stop the volume being resized beyond the end of the partition: https://github.com/maharmstone/btrfs/blob/master/src/fsctl.c#L4858.
Like I said above, there must have been something weird as to how you're exposing the block devices to the VM for it to allow this. I don't think this is an issue with the driver.