mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-11-17 10:01:01 +03:00
Fixing gang ABD when adding another gang
I originally applied a fix in #11539 to fix a parent's child references when a gang ABD is free'd. However, I did not take into account abd_gang_add_gang(). We still need to make sure to update the child references in this function as well. In order to resolve this I removed decreasing the gang ABD's size in abd_free_gang() as well as moved back the original placeent of zfs_refcount_remove_many() in abd_free(). Reviewed-by: Mark Maybee <mark.maybee@delphix.com> Reviewed-by: Matthew Ahrens <mahrens@delphix.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Brian Atkinson <batkinson@lanl.gov> Closes #11542
This commit is contained in:
parent
9f8c7e6a76
commit
2993698eb3
@ -257,11 +257,9 @@ abd_free_gang(abd_t *abd)
|
|||||||
ASSERT(list_link_active(&cabd->abd_gang_link));
|
ASSERT(list_link_active(&cabd->abd_gang_link));
|
||||||
list_remove(&ABD_GANG(abd).abd_gang_chain, cabd);
|
list_remove(&ABD_GANG(abd).abd_gang_chain, cabd);
|
||||||
mutex_exit(&cabd->abd_mtx);
|
mutex_exit(&cabd->abd_mtx);
|
||||||
abd->abd_size -= cabd->abd_size;
|
|
||||||
if (cabd->abd_flags & ABD_FLAG_GANG_FREE)
|
if (cabd->abd_flags & ABD_FLAG_GANG_FREE)
|
||||||
abd_free(cabd);
|
abd_free(cabd);
|
||||||
}
|
}
|
||||||
ASSERT0(abd->abd_size);
|
|
||||||
list_destroy(&ABD_GANG(abd).abd_gang_chain);
|
list_destroy(&ABD_GANG(abd).abd_gang_chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,11 +290,6 @@ abd_free(abd_t *abd)
|
|||||||
abd_verify(abd);
|
abd_verify(abd);
|
||||||
IMPLY(abd->abd_flags & ABD_FLAG_OWNER, abd->abd_parent == NULL);
|
IMPLY(abd->abd_flags & ABD_FLAG_OWNER, abd->abd_parent == NULL);
|
||||||
|
|
||||||
if (abd->abd_parent != NULL) {
|
|
||||||
(void) zfs_refcount_remove_many(&abd->abd_parent->abd_children,
|
|
||||||
abd->abd_size, abd);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (abd_is_gang(abd)) {
|
if (abd_is_gang(abd)) {
|
||||||
abd_free_gang(abd);
|
abd_free_gang(abd);
|
||||||
} else if (abd_is_linear(abd)) {
|
} else if (abd_is_linear(abd)) {
|
||||||
@ -307,6 +300,11 @@ abd_free(abd_t *abd)
|
|||||||
abd_free_scatter(abd);
|
abd_free_scatter(abd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (abd->abd_parent != NULL) {
|
||||||
|
(void) zfs_refcount_remove_many(&abd->abd_parent->abd_children,
|
||||||
|
abd->abd_size, abd);
|
||||||
|
}
|
||||||
|
|
||||||
abd_fini_struct(abd);
|
abd_fini_struct(abd);
|
||||||
if (abd->abd_flags & ABD_FLAG_ALLOCD)
|
if (abd->abd_flags & ABD_FLAG_ALLOCD)
|
||||||
abd_free_struct_impl(abd);
|
abd_free_struct_impl(abd);
|
||||||
@ -366,7 +364,7 @@ abd_gang_add_gang(abd_t *pabd, abd_t *cabd, boolean_t free_on_free)
|
|||||||
&ABD_GANG(cabd).abd_gang_chain);
|
&ABD_GANG(cabd).abd_gang_chain);
|
||||||
ASSERT(list_is_empty(&ABD_GANG(cabd).abd_gang_chain));
|
ASSERT(list_is_empty(&ABD_GANG(cabd).abd_gang_chain));
|
||||||
abd_verify(pabd);
|
abd_verify(pabd);
|
||||||
abd_free_struct(cabd);
|
abd_free(cabd);
|
||||||
} else {
|
} else {
|
||||||
for (abd_t *child = list_head(&ABD_GANG(cabd).abd_gang_chain);
|
for (abd_t *child = list_head(&ABD_GANG(cabd).abd_gang_chain);
|
||||||
child != NULL;
|
child != NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user