Skip to content

Commit 0cb097f

Browse files
asjgregkh
authored andcommitted
btrfs: skip devices without magic signature when mounting
commit 96c2e06 upstream. Many things can happen after the device is scanned and before the device is mounted. One such thing is losing the BTRFS_MAGIC on the device. If it happens we still won't free that device from the memory and cause the userland confusion. For example: As the BTRFS_IOC_DEV_INFO still carries the device path which does not have the BTRFS_MAGIC, 'btrfs fi show' still lists device which does not belong to the filesystem anymore: $ mkfs.btrfs -fq -draid1 -mraid1 /dev/sda /dev/sdb $ wipefs -a /dev/sdb # /dev/sdb does not contain magic signature $ mount -o degraded /dev/sda /btrfs $ btrfs fi show -m Label: none uuid: 470ec6fb-646b-4464-b3cb-df1b26c527bd Total devices 2 FS bytes used 128.00KiB devid 1 size 3.00GiB used 571.19MiB path /dev/sda devid 2 size 3.00GiB used 571.19MiB path /dev/sdb We need to distinguish the missing signature and invalid superblock, so add a specific error code ENODATA for that. This also fixes failure of fstest btrfs/198. CC: stable@vger.kernel.org # 4.19+ Reviewed-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: Anand Jain <anand.jain@oracle.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent fbf3b12 commit 0cb097f

2 files changed

Lines changed: 18 additions & 8 deletions

File tree

fs/btrfs/disk-io.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3482,8 +3482,12 @@ struct btrfs_super_block *btrfs_read_dev_one_super(struct block_device *bdev,
34823482
return ERR_CAST(page);
34833483

34843484
super = page_address(page);
3485-
if (btrfs_super_bytenr(super) != bytenr ||
3486-
btrfs_super_magic(super) != BTRFS_MAGIC) {
3485+
if (btrfs_super_magic(super) != BTRFS_MAGIC) {
3486+
btrfs_release_disk_super(super);
3487+
return ERR_PTR(-ENODATA);
3488+
}
3489+
3490+
if (btrfs_super_bytenr(super) != bytenr) {
34873491
btrfs_release_disk_super(super);
34883492
return ERR_PTR(-EINVAL);
34893493
}

fs/btrfs/volumes.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,17 +1200,23 @@ static int open_fs_devices(struct btrfs_fs_devices *fs_devices,
12001200
{
12011201
struct btrfs_device *device;
12021202
struct btrfs_device *latest_dev = NULL;
1203+
struct btrfs_device *tmp_device;
12031204

12041205
flags |= FMODE_EXCL;
12051206

1206-
list_for_each_entry(device, &fs_devices->devices, dev_list) {
1207-
/* Just open everything we can; ignore failures here */
1208-
if (btrfs_open_one_device(fs_devices, device, flags, holder))
1209-
continue;
1207+
list_for_each_entry_safe(device, tmp_device, &fs_devices->devices,
1208+
dev_list) {
1209+
int ret;
12101210

1211-
if (!latest_dev ||
1212-
device->generation > latest_dev->generation)
1211+
ret = btrfs_open_one_device(fs_devices, device, flags, holder);
1212+
if (ret == 0 &&
1213+
(!latest_dev || device->generation > latest_dev->generation)) {
12131214
latest_dev = device;
1215+
} else if (ret == -ENODATA) {
1216+
fs_devices->num_devices--;
1217+
list_del(&device->dev_list);
1218+
btrfs_free_device(device);
1219+
}
12141220
}
12151221
if (fs_devices->open_devices == 0)
12161222
return -EINVAL;

0 commit comments

Comments
 (0)