Skip to content

Commit b96de00

Browse files
asjmasoncl
authored andcommitted
Btrfs: device_list_add() should not update list when mounted
device_list_add() is called when user runs btrfs dev scan, which would add any btrfs device into the btrfs_fs_devices list. Now think of a mounted btrfs. And a new device which contains the a SB from the mounted btrfs devices. In this situation when user runs btrfs dev scan, the current code would just replace existing device with the new device. Which is to note that old device is neither closed nor gracefully removed from the btrfs. The FS is still operational with the old bdev however the device name is the btrfs_device is new which is provided by the btrfs dev scan. reproducer: devmgt[1] detach /dev/sdc replace the missing disk /dev/sdc btrfs rep start -f 1 /dev/sde /btrfs Label: none uuid: 5dc0aaf4-4683-4050-b2d6-5ebe5f5cd120 Total devices 2 FS bytes used 32.00KiB devid 1 size 958.94MiB used 115.88MiB path /dev/sde devid 2 size 958.94MiB used 103.88MiB path /dev/sdd make /dev/sdc to reappear devmgt attach host2 btrfs dev scan btrfs fi show -m Label: none uuid: 5dc0aaf4-4683-4050-b2d6-5ebe5f5cd120^M Total devices 2 FS bytes used 32.00KiB^M devid 1 size 958.94MiB used 115.88MiB path /dev/sdc <- Wrong. devid 2 size 958.94MiB used 103.88MiB path /dev/sdd since /dev/sdc has been replaced with /dev/sde, the /dev/sdc shouldn't be part of the btrfs-fsid when it reappears. If user want it to be part of it then sys admin should be using btrfs device add instead. [1] github.com/anajain/devmgt.git Signed-off-by: Anand Jain <[email protected]> Signed-off-by: Wang Shilong <[email protected]> Signed-off-by: Miao Xie <[email protected]> Reviewed-by: Satoru Takeuchi <[email protected]> Signed-off-by: Chris Mason <[email protected]>
1 parent 1707e26 commit b96de00

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

fs/btrfs/volumes.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,33 @@ static noinline int device_list_add(const char *path,
508508
ret = 1;
509509
device->fs_devices = fs_devices;
510510
} else if (!device->name || strcmp(device->name->str, path)) {
511+
/*
512+
* When FS is already mounted.
513+
* 1. If you are here and if the device->name is NULL that
514+
* means this device was missing at time of FS mount.
515+
* 2. If you are here and if the device->name is different
516+
* from 'path' that means either
517+
* a. The same device disappeared and reappeared with
518+
* different name. or
519+
* b. The missing-disk-which-was-replaced, has
520+
* reappeared now.
521+
*
522+
* We must allow 1 and 2a above. But 2b would be a spurious
523+
* and unintentional.
524+
*
525+
* Further in case of 1 and 2a above, the disk at 'path'
526+
* would have missed some transaction when it was away and
527+
* in case of 2a the stale bdev has to be updated as well.
528+
* 2b must not be allowed at all time.
529+
*/
530+
531+
/*
532+
* As of now don't allow update to btrfs_fs_device through
533+
* the btrfs dev scan cli, after FS has been mounted.
534+
*/
535+
if (fs_devices->opened)
536+
return -EBUSY;
537+
511538
name = rcu_string_strdup(path, GFP_NOFS);
512539
if (!name)
513540
return -ENOMEM;

0 commit comments

Comments
 (0)