FAILED: patch "[PATCH] btrfs: skip devices without magic signature when mounting" failed to apply to 4.19-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.19-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 96c2e067ed3e3e004580a643c76f58729206b829 Mon Sep 17 00:00:00 2001
From: Anand Jain <[email protected]>
Date: Wed, 30 Sep 2020 21:09:52 +0800
Subject: [PATCH] btrfs: skip devices without magic signature when mounting
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.
fs/btrfs/disk-io.c +6 -2
@@ -3424,8 +3424,12 @@ struct btrfs_super_block *btrfs_read_dev_one_super(struct block_device *bdev,return ERR_CAST (page); super =page_address (page); -if (btrfs_super_bytenr (super) != bytenr || -btrfs_super_magic (super) !=BTRFS_MAGIC ) { +if (btrfs_super_magic (super) !=BTRFS_MAGIC ) { +btrfs_release_disk_super (super); +return ERR_PTR (-ENODATA ); + } + +if (btrfs_super_bytenr (super) != bytenr) {btrfs_release_disk_super (super);return ERR_PTR (-EINVAL ); }
fs/btrfs/volumes.c +12 -6
@@ -1198,17 +1198,23 @@ static int open_fs_devices(struct btrfs_fs_devices *fs_devices, {struct btrfs_device *device;struct btrfs_device *latest_dev =NULL ; +struct btrfs_device *tmp_device; flags |=FMODE_EXCL ; -list_for_each_entry (device, &fs_devices->devices, dev_list) { -/* Just open everything we can; ignore failures here */ -if (btrfs_open_one_device (fs_devices, device, flags, holder)) -continue ; +list_for_each_entry_safe (device, tmp_device, &fs_devices->devices, + dev_list) { +int ret; -if (!latest_dev || - device->generation > latest_dev->generation) + ret =btrfs_open_one_device (fs_devices, device, flags, holder); +if (ret ==0 && + (!latest_dev || device->generation > latest_dev->generation)) { latest_dev = device; + }else if (ret == -ENODATA ) { + fs_devices->num_devices--; +list_del (&device->dev_list); +btrfs_free_device (device); + } }if (fs_devices->open_devices ==0 )return -EINVAL ;