Commit 02f5a09e authored by Mark Fasheh's avatar Mark Fasheh

run_dedupe: avoid size_list corruption in push_blocks()

Each thread frees the corresponding dups list structure, but in doing so
will remove it from the size list. When this happens it corrupts the list
for push_blocks(). Remove it from the size_list in push_blocks() instead so
we don't have this situation later.
Signed-off-by: 's avatarMark Fasheh <mfasheh@suse.de>
parent d23b27ca
......@@ -353,6 +353,7 @@ int remove_hashed_block(struct hash_tree *tree,
if (head && list_empty(&head->h_blocks))
free_one_hash_head(blocklist, head);
abort_on(blocklist->dl_num_elem == 0);
blocklist->dl_num_elem--;
if (blocklist->dl_num_elem == 0) {
rb_erase(&blocklist->dl_node, &tree->root);
......
......@@ -814,11 +814,17 @@ out:
static int push_blocks(struct hash_tree *hashes)
{
struct dupe_blocks_list *dups;
struct dupe_blocks_list *dups, *tmp;
list_for_each_entry(dups, &hashes->size_list, dl_size_list) {
list_for_each_entry_safe(dups, tmp, &hashes->size_list, dl_size_list) {
if (dups->dl_num_elem < 2)
continue;
/*
* Do this here because we don't want one of the
* worker threads removing it from the size list for
* us when they free the dups structure.
*/
list_del_init(&dups->dl_size_list);
if (__push_blocks(hashes, dups))
return 1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment