|
Qu Wenruo |
10952e |
From a9261d4125c97ce8624e9941b75dee1b43ad5df9 Mon Sep 17 00:00:00 2001
|
|
Qu Wenruo |
10952e |
Patch-mainline: v5.1
|
|
Qu Wenruo |
10952e |
References: bsc#1134973
|
|
Qu Wenruo |
10952e |
Git-commit: a9261d4125c97ce8624e9941b75dee1b43ad5df9
|
|
Qu Wenruo |
10952e |
From: Anand Jain <anand.jain@oracle.com>
|
|
Qu Wenruo |
10952e |
Date: Mon, 15 Oct 2018 10:45:17 +0800
|
|
Qu Wenruo |
10952e |
Subject: [PATCH] btrfs: harden agaist duplicate fsid on scanned devices
|
|
Qu Wenruo |
10952e |
|
|
Qu Wenruo |
10952e |
It's not that impossible to imagine that a device OR a btrfs image is
|
|
Qu Wenruo |
10952e |
copied just by using the dd or the cp command. Which in case both the
|
|
Qu Wenruo |
10952e |
copies of the btrfs will have the same fsid. If on the system with
|
|
Qu Wenruo |
10952e |
automount enabled, the copied FS gets scanned.
|
|
Qu Wenruo |
10952e |
|
|
Qu Wenruo |
10952e |
We have a known bug in btrfs, that we let the device path be changed
|
|
Qu Wenruo |
10952e |
after the device has been mounted. So using this loop hole the new
|
|
Qu Wenruo |
10952e |
copied device would appears as if its mounted immediately after it's
|
|
Qu Wenruo |
10952e |
been copied.
|
|
Qu Wenruo |
10952e |
|
|
Qu Wenruo |
10952e |
For example:
|
|
Qu Wenruo |
10952e |
|
|
Qu Wenruo |
10952e |
Initially.. /dev/mmcblk0p4 is mounted as /
|
|
Qu Wenruo |
10952e |
|
|
Qu Wenruo |
10952e |
$ lsblk
|
|
Qu Wenruo |
10952e |
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
|
|
Qu Wenruo |
10952e |
mmcblk0 179:0 0 29.2G 0 disk
|
|
Qu Wenruo |
10952e |
|-mmcblk0p4 179:4 0 4G 0 part /
|
|
Qu Wenruo |
10952e |
|-mmcblk0p2 179:2 0 500M 0 part /boot
|
|
Qu Wenruo |
10952e |
|-mmcblk0p3 179:3 0 256M 0 part [SWAP]
|
|
Qu Wenruo |
10952e |
`-mmcblk0p1 179:1 0 256M 0 part /boot/efi
|
|
Qu Wenruo |
10952e |
|
|
Qu Wenruo |
10952e |
$ btrfs fi show
|
|
Qu Wenruo |
10952e |
Label: none uuid: 07892354-ddaa-4443-90ea-f76a06accaba
|
|
Qu Wenruo |
10952e |
Total devices 1 FS bytes used 1.40GiB
|
|
Qu Wenruo |
10952e |
devid 1 size 4.00GiB used 3.00GiB path /dev/mmcblk0p4
|
|
Qu Wenruo |
10952e |
|
|
Qu Wenruo |
10952e |
Copy mmcblk0 to sda
|
|
Qu Wenruo |
10952e |
|
|
Qu Wenruo |
10952e |
$ dd if=/dev/mmcblk0 of=/dev/sda
|
|
Qu Wenruo |
10952e |
|
|
Qu Wenruo |
10952e |
And immediately after the copy completes the change in the device
|
|
Qu Wenruo |
10952e |
superblock is notified which the automount scans using btrfs device scan
|
|
Qu Wenruo |
10952e |
and the new device sda becomes the mounted root device.
|
|
Qu Wenruo |
10952e |
|
|
Qu Wenruo |
10952e |
$ lsblk
|
|
Qu Wenruo |
10952e |
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
|
|
Qu Wenruo |
10952e |
sda 8:0 1 14.9G 0 disk
|
|
Qu Wenruo |
10952e |
|-sda4 8:4 1 4G 0 part /
|
|
Qu Wenruo |
10952e |
|-sda2 8:2 1 500M 0 part
|
|
Qu Wenruo |
10952e |
|-sda3 8:3 1 256M 0 part
|
|
Qu Wenruo |
10952e |
`-sda1 8:1 1 256M 0 part
|
|
Qu Wenruo |
10952e |
mmcblk0 179:0 0 29.2G 0 disk
|
|
Qu Wenruo |
10952e |
|-mmcblk0p4 179:4 0 4G 0 part
|
|
Qu Wenruo |
10952e |
|-mmcblk0p2 179:2 0 500M 0 part /boot
|
|
Qu Wenruo |
10952e |
|-mmcblk0p3 179:3 0 256M 0 part [SWAP]
|
|
Qu Wenruo |
10952e |
`-mmcblk0p1 179:1 0 256M 0 part /boot/efi
|
|
Qu Wenruo |
10952e |
|
|
Qu Wenruo |
10952e |
$ btrfs fi show /
|
|
Qu Wenruo |
10952e |
Label: none uuid: 07892354-ddaa-4443-90ea-f76a06accaba
|
|
Qu Wenruo |
10952e |
Total devices 1 FS bytes used 1.40GiB
|
|
Qu Wenruo |
10952e |
devid 1 size 4.00GiB used 3.00GiB path /dev/sda4
|
|
Qu Wenruo |
10952e |
|
|
Qu Wenruo |
10952e |
The bug is quite nasty that you can't either unmount /dev/sda4 or
|
|
Qu Wenruo |
10952e |
/dev/mmcblk0p4. And the problem does not get solved until you take sda
|
|
Qu Wenruo |
10952e |
out of the system on to another system to change its fsid using the
|
|
Qu Wenruo |
10952e |
'btrfstune -u' command.
|
|
Qu Wenruo |
10952e |
|
|
Qu Wenruo |
10952e |
Signed-off-by: Anand Jain <anand.jain@oracle.com>
|
|
Qu Wenruo |
10952e |
Reviewed-by: David Sterba <dsterba@suse.com>
|
|
Qu Wenruo |
10952e |
Signed-off-by: David Sterba <dsterba@suse.com>
|
|
Qu Wenruo |
10952e |
Signed-off-by: Qu Wenruo <wqu@suse.com>
|
|
Qu Wenruo |
10952e |
---
|
|
Qu Wenruo |
10952e |
fs/btrfs/volumes.c | 29 +++++++++++++++++++++++++++++
|
|
Qu Wenruo |
10952e |
1 file changed, 29 insertions(+)
|
|
Qu Wenruo |
10952e |
|
|
Qu Wenruo |
10952e |
--- a/fs/btrfs/volumes.c
|
|
Qu Wenruo |
10952e |
+++ b/fs/btrfs/volumes.c
|
|
Qu Wenruo |
10952e |
@@ -641,6 +641,35 @@ static noinline int device_list_add(cons
|
|
Qu Wenruo |
10952e |
return PTR_ERR(device);
|
|
Qu Wenruo |
10952e |
}
|
|
Qu Wenruo |
10952e |
|
|
Qu Wenruo |
10952e |
+ /*
|
|
Qu Wenruo |
10952e |
+ * We are going to replace the device path for a given devid,
|
|
Qu Wenruo |
10952e |
+ * make sure it's the same device if the device is mounted
|
|
Qu Wenruo |
10952e |
+ */
|
|
Qu Wenruo |
10952e |
+ if (device->bdev) {
|
|
Qu Wenruo |
10952e |
+ struct block_device *path_bdev;
|
|
Qu Wenruo |
10952e |
+
|
|
Qu Wenruo |
10952e |
+ path_bdev = lookup_bdev(path);
|
|
Qu Wenruo |
10952e |
+ if (IS_ERR(path_bdev)) {
|
|
Qu Wenruo |
10952e |
+ mutex_unlock(&fs_devices->device_list_mutex);
|
|
Qu Wenruo |
752785 |
+ return PTR_ERR(path_bdev);
|
|
Qu Wenruo |
10952e |
+ }
|
|
Qu Wenruo |
10952e |
+
|
|
Qu Wenruo |
10952e |
+ if (device->bdev != path_bdev) {
|
|
Qu Wenruo |
10952e |
+ bdput(path_bdev);
|
|
Qu Wenruo |
10952e |
+ mutex_unlock(&fs_devices->device_list_mutex);
|
|
Qu Wenruo |
10952e |
+ btrfs_warn_in_rcu(device->fs_info,
|
|
Qu Wenruo |
10952e |
+ "duplicate device fsid:devid for %pU:%llu old:%s new:%s",
|
|
Qu Wenruo |
10952e |
+ disk_super->fsid, devid,
|
|
Qu Wenruo |
10952e |
+ rcu_str_deref(device->name), path);
|
|
Qu Wenruo |
752785 |
+ return -EEXIST;
|
|
Qu Wenruo |
10952e |
+ }
|
|
Qu Wenruo |
10952e |
+ bdput(path_bdev);
|
|
Qu Wenruo |
10952e |
+ btrfs_info_in_rcu(device->fs_info,
|
|
Qu Wenruo |
10952e |
+ "device fsid %pU devid %llu moved old:%s new:%s",
|
|
Qu Wenruo |
10952e |
+ disk_super->fsid, devid,
|
|
Qu Wenruo |
10952e |
+ rcu_str_deref(device->name), path);
|
|
Qu Wenruo |
10952e |
+ }
|
|
Qu Wenruo |
10952e |
+
|
|
Qu Wenruo |
10952e |
name = rcu_string_strdup(path, GFP_NOFS);
|
|
Qu Wenruo |
10952e |
if (!name) {
|
|
Qu Wenruo |
10952e |
kfree(device);
|