btrfs-progs: change-csum: handle finished dev-replace correctly
[BUG] If a btrfs filesystem had dev-replace ran in the past, even it's already finished, btrfstune would refuse to change its csum: WARNING: Experimental build with unstable or unfinished features WARNING: Switching checksums is experimental, do not use for valuable data! Proceed to switch checksums ERROR: running dev-replace detected, please finish or cancel it. ERROR: btrfstune failed [CAUSE] The current dev-replace detection is only checking if we have DEV_REPLACE item in device tree. However DEV_REPLACE item will also exist even if a dev-replace finished, so the existing check can not handle such case at all. [FIX] If an dev-replace item is found, further check the state of the item to prevent false alerts. Issue: #798 Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
6ad89f67a9
commit
6a3e646139
|
@ -73,16 +73,27 @@ static int check_csum_change_requreiment(struct btrfs_fs_info *fs_info, u16 new_
|
|||
key.type = BTRFS_DEV_REPLACE_KEY;
|
||||
key.offset = 0;
|
||||
ret = btrfs_search_slot(NULL, dev_root, &key, &path, 0, 0);
|
||||
btrfs_release_path(&path);
|
||||
if (ret < 0) {
|
||||
btrfs_release_path(&path);
|
||||
errno = -ret;
|
||||
error("failed to check the dev-replace status: %m");
|
||||
return ret;
|
||||
}
|
||||
if (ret == 0) {
|
||||
error("running dev-replace detected, please finish or cancel it.");
|
||||
struct btrfs_dev_replace_item *ptr;
|
||||
u64 state;
|
||||
|
||||
ptr = btrfs_item_ptr(path.nodes[0], path.slots[0], struct btrfs_dev_replace_item);
|
||||
state = btrfs_dev_replace_replace_state(path.nodes[0], ptr);
|
||||
if (state == BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED ||
|
||||
state == BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED) {
|
||||
btrfs_release_path(&path);
|
||||
error(
|
||||
"running/suspended dev-replace detected, please finish or cancel it");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
btrfs_release_path(&path);
|
||||
|
||||
if (fs_info->csum_type == new_csum_type) {
|
||||
error("the fs is already using csum type %s (%u)",
|
||||
|
|
Loading…
Reference in New Issue