On 2018年04月25日 13:19, Su Yue wrote:
> For an extent item which contains many tree block backrefs, like
> =================================================================
> In 020-extent-ref-cases/keyed_block_ref.img
>
> item 10 key (29470720 METADATA_ITEM 0) itemoff 3450 itemsize 222
> refs 23 gen 10 flags TREE_BLOCK
> tree block skinny level 0
> tree block backref root 278
> tree block backref root 277
> tree block backref root 276
> tree block backref root 275
> tree block backref root 274
> tree block backref root 273
> tree block backref root 272
> tree block backref root 271
> tree block backref root 270
> tree block backref root 269
> tree block backref root 268
> tree block backref root 267
> tree block backref root 266
> tree block backref root 265
> tree block backref root 264
> tree block backref root 263
> tree block backref root 262
> tree block backref root 261
> tree block backref root 260
> tree block backref root 259
> tree block backref root 258
> tree block backref root 257
> =================================================================
> In find_parent_nodes(), these refs's parents are 0, then __merge_refs
> will merge refs to one ref. It causes only one root to be returned.
>
> So, if both parents are 0, do not merge refs.
>
> Lowmem check calls find_parent_nodes frequently to decide whether
> check an extent buffer or not. The bug influences bytes accounting.
>
> Signed-off-by: Su Yue <suy.fnst@xxxxxxxxxxxxxx>
Reviewed-by: Qu Wenruo <wqu@xxxxxxxx>
Waiting for the kernel port of backref.c to solve the problem permanently.
Thanks,
Qu
> ---
> Changelog:
> v2:
> Put judgment of ref->parent above comparison.
> Add the comment.
> Fix typos.
> v2.1:
> Remove the change of adding a new line.
> ---
> backref.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/backref.c b/backref.c
> index 51553c702187..23a394edfd02 100644
> --- a/backref.c
> +++ b/backref.c
> @@ -505,6 +505,12 @@ static void __merge_refs(struct pref_state *prefstate, int mode)
> if (!ref_for_same_block(ref1, ref2))
> continue;
> } else {
> + /*
> + * Parent == 0 means that the ref is tree block
> + * backref or its parent is unresolved.
> + */
> + if (!ref1->parent || !ref2->parent)
> + continue;
> if (ref1->parent != ref2->parent)
> continue;
> }
>
Attachment:
signature.asc
Description: OpenPGP digital signature
