On 12.12.19 г. 13:01 ч., damenly.su@xxxxxxxxx wrote:
> From: Su Yue <Damenly_Su@xxxxxxx>
>
> This patch adds the case for scanned changing device with
> INCOMPAT_METADATA_UUID.
> For this situation, the origin code only handles the case
> the devices already pulled into disk with INCOMPAT_METADATA_UUID set.
> There is an another case that the successful changed devices synced
> without INCOMPAT_METADATA_UUID.
> So add the check of Heather fsid of scanned device equals
> metadata_uuid of fs_devices which is with INCOMPAT_METADATA_UUID
> feature.
>
This is hard for me to parse and correctly understand what you mean.
> Signed-off-by: Su Yue <Damenly_Su@xxxxxxx>
> ---
> fs/btrfs/volumes.c | 29 ++++++++++++++++++++++++++---
> 1 file changed, 26 insertions(+), 3 deletions(-)
>
> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
> index b08b06a89a77..61b4a107bb58 100644
> --- a/fs/btrfs/volumes.c
> +++ b/fs/btrfs/volumes.c
> @@ -654,7 +654,6 @@ static struct btrfs_fs_devices *find_fsid_inprogress(
> return NULL;
> }
>
> -
> static struct btrfs_fs_devices *find_fsid_changed(
> struct btrfs_super_block *disk_super)
find_fsid_changed handles the case where a device belongs to a
filesystem which had multiple successful fsid changed but it failed on
the last one.
> {
> @@ -663,9 +662,14 @@ static struct btrfs_fs_devices *find_fsid_changed(
> /*
> * Handles the case where scanned device is part of an fs that had
> * multiple successful changes of FSID but curently device didn't
> - * observe it. Meaning our fsid will be different than theirs.
> + * observe it.
> + *
> + * Case 1: the devices already changed still owns the feature, their
> + * fsid must differ from the disk_super->fsid.
What do you mean by device to still owns the feature? Has the bit set or
something else?
> */
> list_for_each_entry(fs_devices, &fs_uuids, fs_list) {
> + if (fs_devices->fsid_change)
> + continue;
Why do you do this?
> if (memcmp(fs_devices->metadata_uuid, fs_devices->fsid,
> BTRFS_FSID_SIZE) != 0 &&
> memcmp(fs_devices->metadata_uuid, disk_super->metadata_uuid,
> @@ -676,7 +680,26 @@ static struct btrfs_fs_devices *find_fsid_changed(
> }
> }
>
> - return NULL;
> + /*
> + * Case 2: the synced devices doesn't have the metadata_uuid feature.
> + * NOTE: the fs_devices has same metadata_uuid and fsid in memory, but
> + * they differs in disk, because fs_id is copied to
> + * fs_devices->metadata_id while alloc_fs_devices if no metadata
It's not possible for the device to have metadata_uuid feature because
this function is called from device_list_add iff the device has
METADATA_UUID flag:
if (fsid_change_in_progress) {
if (!has_metadata_uuid) {
} else {
find_fsid_changed <-- here we are sure our device has METADATA_UUID set.
}
}
> + * feature.
> + */
> + list_for_each_entry(fs_devices, &fs_uuids, fs_list) {
> + if (memcmp(fs_devices->metadata_uuid, fs_devices->fsid,
> + BTRFS_FSID_SIZE) == 0 &&
> + memcmp(fs_devices->fsid, disk_super->metadata_uuid,
> + BTRFS_FSID_SIZE) == 0 && !fs_devices->fsid_change)
> + return fs_devices;
> + }
> +
> + /*
> + * Okay, can't found any fs_devices already synced, back to
> + * search devices unchanged or changing like the device.
> + */
> + return find_fsid(disk_super->fsid, disk_super->metadata_uuid);
> }
>
> static struct btrfs_fs_devices *find_fsid_changing_metada_uuid(
>