> > +/* > > + * 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.