Fix deadlock related to chunk_record().
Fix chunk_record() to unlock chunks_mtx before deallocating a base node, in order to avoid potential deadlock. Reported by Tudor Bosman.
This commit is contained in:
parent
705328ca46
commit
741fbc6ba4
15
src/chunk.c
15
src/chunk.c
@ -242,8 +242,6 @@ chunk_record(extent_tree_t *chunks_szad, extent_tree_t *chunks_ad, void *chunk,
|
|||||||
node->size += size;
|
node->size += size;
|
||||||
node->zeroed = (node->zeroed && (unzeroed == false));
|
node->zeroed = (node->zeroed && (unzeroed == false));
|
||||||
extent_tree_szad_insert(chunks_szad, node);
|
extent_tree_szad_insert(chunks_szad, node);
|
||||||
if (xnode != NULL)
|
|
||||||
base_node_dealloc(xnode);
|
|
||||||
} else {
|
} else {
|
||||||
/* Coalescing forward failed, so insert a new node. */
|
/* Coalescing forward failed, so insert a new node. */
|
||||||
if (xnode == NULL) {
|
if (xnode == NULL) {
|
||||||
@ -253,10 +251,10 @@ chunk_record(extent_tree_t *chunks_szad, extent_tree_t *chunks_ad, void *chunk,
|
|||||||
* already been purged, so this is only a virtual
|
* already been purged, so this is only a virtual
|
||||||
* memory leak.
|
* memory leak.
|
||||||
*/
|
*/
|
||||||
malloc_mutex_unlock(&chunks_mtx);
|
goto label_return;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
node = xnode;
|
node = xnode;
|
||||||
|
xnode = NULL; /* Prevent deallocation below. */
|
||||||
node->addr = chunk;
|
node->addr = chunk;
|
||||||
node->size = size;
|
node->size = size;
|
||||||
node->zeroed = (unzeroed == false);
|
node->zeroed = (unzeroed == false);
|
||||||
@ -284,7 +282,16 @@ chunk_record(extent_tree_t *chunks_szad, extent_tree_t *chunks_ad, void *chunk,
|
|||||||
|
|
||||||
base_node_dealloc(prev);
|
base_node_dealloc(prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
label_return:
|
||||||
malloc_mutex_unlock(&chunks_mtx);
|
malloc_mutex_unlock(&chunks_mtx);
|
||||||
|
if (xnode != NULL) {
|
||||||
|
/*
|
||||||
|
* Deallocate xnode after unlocking chunks_mtx in order to
|
||||||
|
* avoid potential deadlock.
|
||||||
|
*/
|
||||||
|
base_node_dealloc(xnode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user