Fix panic in dsl_process_sub_livelist for EINTR
= Issue Recently we hit an assertion panic in `dsl_process_sub_livelist` while exporting the spa and interrupting `bpobj_iterate_nofree`. In that case `bpobj_iterate_nofree` stops mid-way returning an EINTR without clearing the intermediate AVL tree that keeps track of the livelist entries it has encountered so far. At that point the code has a VERIFY for the number of elements of the AVL expecting it to be zero (which is not the case for EINTR). = Fix Cleanup any intermediate state before destroying the AVL when encountering EINTR. Also added a comment documenting the scenario where the EINTR comes up. There is no need to do anything else for the calles of `dsl_process_sub_livelist` as they already handle the EINTR case. Reviewed-by: Matthew Ahrens <mahrens@delphix.com> Reviewed-by: Mark Maybee <mark.maybee@delphix.com> Reviewed-by: Richard Yao <richard.yao@alumni.stonybrook.edu> Signed-off-by: Serapheim Dimitropoulos <serapheim@delphix.com> Closes #13939
This commit is contained in:
parent
c8d6a91a99
commit
37763ea2a6
|
@ -1028,8 +1028,13 @@ dsl_process_sub_livelist(bpobj_t *bpobj, bplist_t *to_free, zthr_t *t,
|
|||
.t = t
|
||||
};
|
||||
int err = bpobj_iterate_nofree(bpobj, dsl_livelist_iterate, &arg, size);
|
||||
VERIFY(err != 0 || avl_numnodes(&avl) == 0);
|
||||
|
||||
VERIFY0(avl_numnodes(&avl));
|
||||
void *cookie = NULL;
|
||||
livelist_entry_t *le = NULL;
|
||||
while ((le = avl_destroy_nodes(&avl, &cookie)) != NULL) {
|
||||
kmem_free(le, sizeof (livelist_entry_t));
|
||||
}
|
||||
avl_destroy(&avl);
|
||||
return (err);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue