Skip to content

Commit

Permalink
Fix panic in dsl_process_sub_livelist for EINTR
Browse files Browse the repository at this point in the history
= 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 openzfs#13939
  • Loading branch information
sdimitro authored and andrewc12 committed Oct 2, 2022
1 parent 9e02fac commit e9d3731
Showing 1 changed file with 6 additions and 1 deletion.
7 changes: 6 additions & 1 deletion module/zfs/dsl_deadlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down

0 comments on commit e9d3731

Please sign in to comment.