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.type = BTRFS_DEV_REPLACE_KEY;
|
||||||
key.offset = 0;
|
key.offset = 0;
|
||||||
ret = btrfs_search_slot(NULL, dev_root, &key, &path, 0, 0);
|
ret = btrfs_search_slot(NULL, dev_root, &key, &path, 0, 0);
|
||||||
btrfs_release_path(&path);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
btrfs_release_path(&path);
|
||||||
errno = -ret;
|
errno = -ret;
|
||||||
error("failed to check the dev-replace status: %m");
|
error("failed to check the dev-replace status: %m");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
error("running dev-replace detected, please finish or cancel it.");
|
struct btrfs_dev_replace_item *ptr;
|
||||||
return -EINVAL;
|
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) {
|
if (fs_info->csum_type == new_csum_type) {
|
||||||
error("the fs is already using csum type %s (%u)",
|
error("the fs is already using csum type %s (%u)",
|
||||||
|
|
Loading…
Reference in New Issue