mirror of
https://github.com/kdave/btrfs-progs
synced 2024-12-28 09:02:19 +00:00
btrfs-progs: tune: add the ability to migrate the temporary csum items to regular csum items
At this stage, the csum tree should only contain the temporary csum items (CSUM_CHANGE, EXTENT_CSUM, logical), and no more old csum items. Now we can convert those temporary csum items back to regular csum items by changing their key objectids back to EXTENT_CSUM. Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
4cf02fbc84
commit
87016bffbb
@ -388,6 +388,89 @@ static int delete_old_data_csums(struct btrfs_fs_info *fs_info)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int change_csum_objectids(struct btrfs_fs_info *fs_info)
|
||||
{
|
||||
struct btrfs_root *csum_root = btrfs_csum_root(fs_info, 0);
|
||||
struct btrfs_trans_handle *trans;
|
||||
struct btrfs_path path = { 0 };
|
||||
struct btrfs_key last_key;
|
||||
u64 super_flags;
|
||||
int ret = 0;
|
||||
|
||||
last_key.objectid = BTRFS_CSUM_CHANGE_OBJECTID;
|
||||
last_key.type = BTRFS_EXTENT_CSUM_KEY;
|
||||
last_key.offset = (u64)-1;
|
||||
|
||||
trans = btrfs_start_transaction(csum_root, 1);
|
||||
if (IS_ERR(trans)) {
|
||||
ret = PTR_ERR(trans);
|
||||
errno = -ret;
|
||||
error("failed to start transaction to change csum objectids: %m");
|
||||
return ret;
|
||||
}
|
||||
while (true) {
|
||||
struct btrfs_key found_key;
|
||||
int nr;
|
||||
|
||||
ret = btrfs_search_slot(trans, csum_root, &last_key, &path, 0, 1);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
assert(ret > 0);
|
||||
|
||||
nr = btrfs_header_nritems(path.nodes[0]);
|
||||
/* No item left (empty csum tree), exit. */
|
||||
if (!nr)
|
||||
goto out;
|
||||
/* No more temporary csum items, all converted, exit. */
|
||||
if (path.slots[0] == 0)
|
||||
goto out;
|
||||
|
||||
/* All csum items should be new csums. */
|
||||
btrfs_item_key_to_cpu(path.nodes[0], &found_key, 0);
|
||||
assert(found_key.objectid == BTRFS_CSUM_CHANGE_OBJECTID);
|
||||
|
||||
/*
|
||||
* Start changing the objectids, since EXTENT_CSUM (-10) is
|
||||
* larger than CSUM_CHANGE (-13), we always change from the tail.
|
||||
*/
|
||||
for (int i = nr - 1; i >= 0; i--) {
|
||||
btrfs_item_key_to_cpu(path.nodes[0], &found_key, i);
|
||||
found_key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
|
||||
path.slots[0] = i;
|
||||
ret = btrfs_set_item_key_safe(csum_root, &path, &found_key);
|
||||
if (ret < 0) {
|
||||
errno = -ret;
|
||||
error("failed to set item key for data csum at logical %llu: %m",
|
||||
found_key.offset);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
btrfs_release_path(&path);
|
||||
}
|
||||
out:
|
||||
btrfs_release_path(&path);
|
||||
if (ret < 0) {
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* All data csum items has been changed to the new type, we can clear
|
||||
* the superblock flag for data csum change, and go to the metadata csum
|
||||
* change phase.
|
||||
*/
|
||||
super_flags = btrfs_super_flags(fs_info->super_copy);
|
||||
super_flags &= ~BTRFS_SUPER_FLAG_CHANGING_DATA_CSUM;
|
||||
super_flags |= BTRFS_SUPER_FLAG_CHANGING_META_CSUM;
|
||||
btrfs_set_super_flags(fs_info->super_copy, super_flags);
|
||||
ret = btrfs_commit_transaction(trans, csum_root);
|
||||
if (ret < 0) {
|
||||
errno = -ret;
|
||||
error("failed to commit transaction after changing data csum objectids: %m");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int btrfs_change_csum_type(struct btrfs_fs_info *fs_info, u16 new_csum_type)
|
||||
{
|
||||
int ret;
|
||||
@ -417,6 +500,9 @@ int btrfs_change_csum_type(struct btrfs_fs_info *fs_info, u16 new_csum_type)
|
||||
return ret;
|
||||
|
||||
/* Phase 3, change the new csum key objectid */
|
||||
ret = change_csum_objectids(fs_info);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Phase 4, change the csums for metadata.
|
||||
|
Loading…
Reference in New Issue
Block a user