> > +/*
> > + * Build a QCowHashNode from a given QCowHash and insert it into the tree
> > + *
> > + * @hash: the given QCowHash
> > + */
> > +static void qcow2_build_and_insert_hash_node(BlockDriverState *bs,
> > + QCowHash *hash)
> > +{
> > + BDRVQcowState *s = bs->opaque;
> > + QCowHashNode *hash_node;
> > +
> > + /* build the hash node with QCOW_FLAG_EMPTY as offsets so we will
> > remember
> > + * to fill these field later with real values.
> > + */
> > + hash_node = qcow2_dedup_build_qcow_hash_node(hash,
> > + QCOW_FLAG_EMPTY,
> > + QCOW_FLAG_EMPTY);
> > + g_tree_insert(s->dedup_tree_by_hash, &hash_node->hash, hash_node);
> > +}
>
> Interesting function, it doesn't return hash_node. Someone will have to
> look it up.
>
> Also, we put an incomplete node into dedup_tree_by_hash. The caller
> must ensure that other coroutines do not use dedup_tree_by_hash() before
> we've filled in real values, or the callers need to check for
> QCOW_FLAG_EMPTY. Seems a little risky, so why insert before completing
> the hash node?
>
It's done like this so the next iteration of the deduplication loop
will find that a cluster is duplicated if so and stop rigth here.
I can fill the missing information of the qcow hash node only long after that
when the new cluster cluster is allocated.