btrfs: defrag: fix key comparison with max defrag key in btrfs_defrag_leaves()

The comparison can not be done in isolation for each key component (type
and offset) after the objectid component. For example if the defrag_max
key is (300 2 0) and the defrag_progress key is (301 1 0), the existing
comparison makes us jump to the 'done' label with 'ret' set to -EAGAIN
because 2 > 1, resulting in continuing to defrag despite having passed
the objectid of 300.

Fix this by doing the comparison correctly with btrfs_comp_cpu_keys().

Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Filipe Manana 2026-10-07 15:41:21 +01:00 committed by David Sterba
parent bbb86c6dc1
commit 04136cd21c

View File

@ -530,11 +530,7 @@ static int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
out:
btrfs_free_path(path);
if (ret == -EAGAIN) {
if (root->defrag_max.objectid > root->defrag_progress.objectid)
goto done;
if (root->defrag_max.type > root->defrag_progress.type)
goto done;
if (root->defrag_max.offset > root->defrag_progress.offset)
if (btrfs_comp_cpu_keys(&root->defrag_max, &root->defrag_progress) > 0)
goto done;
ret = 0;
}