mirror of
https://github.com/kdave/btrfs-progs
synced 2024-12-13 01:46:14 +00:00
btrfs-progs: backref: properly queue indirect refs
[BUG] When calling iterate_extent_inodes() on data extents with indirect ref (with inline or keyed EXTENT_DATA_REF_KEY), it will fail to execute the call back function at all. [CAUSE] In function find_parent_nodes(), we only add the target tree block if a backref has @parent populated. For indirect backref like EXTENT_DATA_REF_KEY, we rely on __resolve_indirect_ref() to get the parent leaves. However __resolve_indirect_ref() only grabs backrefs from &prefstate->pending_indirect_refs. Meaning callers should queue any indirect backref to pending_indirect_refs. But unfortunately in __add_prelim_ref() and __add_missing_keys(), none of them properly queue the indirect backrefs to pending_indirect_refs, but directly to pending. Making all indirect backrefs never got resolved, thus no callback function executed [FIX] Fix __add_prelim_ref() and __add_missing_keys() to properly queue indirect backrefs to the correct list. Currently there is no such direct user in btrfs-progs, but later csum tree re-initialization code will rely this to do proper csum re-calculate (to avoid preallocated/nodatasum extents). Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
d6ee42633b
commit
90cdc23d01
@ -192,7 +192,10 @@ static int __add_prelim_ref(struct pref_state *prefstate, u64 root_id,
|
|||||||
ref->root_id = root_id;
|
ref->root_id = root_id;
|
||||||
if (key) {
|
if (key) {
|
||||||
ref->key_for_search = *key;
|
ref->key_for_search = *key;
|
||||||
head = &prefstate->pending;
|
if (parent)
|
||||||
|
head = &prefstate->pending;
|
||||||
|
else
|
||||||
|
head = &prefstate->pending_indirect_refs;
|
||||||
} else if (parent) {
|
} else if (parent) {
|
||||||
memset(&ref->key_for_search, 0, sizeof(ref->key_for_search));
|
memset(&ref->key_for_search, 0, sizeof(ref->key_for_search));
|
||||||
head = &prefstate->pending;
|
head = &prefstate->pending;
|
||||||
@ -467,7 +470,10 @@ static int __add_missing_keys(struct btrfs_fs_info *fs_info,
|
|||||||
else
|
else
|
||||||
btrfs_node_key_to_cpu(eb, &ref->key_for_search, 0);
|
btrfs_node_key_to_cpu(eb, &ref->key_for_search, 0);
|
||||||
free_extent_buffer(eb);
|
free_extent_buffer(eb);
|
||||||
list_move(&ref->list, &prefstate->pending);
|
if (ref->parent)
|
||||||
|
list_move(&ref->list, &prefstate->pending);
|
||||||
|
else
|
||||||
|
list_move(&ref->list, &prefstate->pending_indirect_refs);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user