Skip to content

Commit

Permalink
ZIL: Fix potential race on flush deferring.
Browse files Browse the repository at this point in the history
zil_lwb_set_zio_dependency() can not set write ZIO dependency on
previous LWB's write ZIO if one is already in done handler and set
state to LWB_STATE_WRITE_DONE.  So theoretically done handler of
next LWB's write ZIO may run before done handler of previous LWB
write ZIO completes.  In such case we can not defer flushes, since
the flush issue process is not locked.

This may fix some reported assertions of lwb_vdev_tree not being
empty inside zil_free_lwb().

Signed-off-by:	Alexander Motin <[email protected]>
Sponsored by:	iXsystems, Inc.
  • Loading branch information
amotin committed Sep 18, 2023
1 parent 9192ab7 commit 8710d10
Showing 1 changed file with 9 additions and 0 deletions.
9 changes: 9 additions & 0 deletions module/zfs/zil.c
Original file line number Diff line number Diff line change
Expand Up @@ -1550,7 +1550,16 @@ zil_lwb_write_done(zio_t *zio)
lwb->lwb_state = LWB_STATE_WRITE_DONE;
lwb->lwb_child_zio = NULL;
lwb->lwb_write_zio = NULL;

/*
* If nlwb is not yet issued, zil_lwb_set_zio_dependency() is not
* called for it yet, and when it will be, it won't be able to make
* its write ZIO a parent this ZIO. In such case we can not defer
* our flushes or below may be a race between the done callbacks.
*/
nlwb = list_next(&zilog->zl_lwb_list, lwb);
if (nlwb && nlwb->lwb_state != LWB_STATE_ISSUED)
nlwb = NULL;
mutex_exit(&zilog->zl_lock);

if (avl_numnodes(t) == 0)
Expand Down

0 comments on commit 8710d10

Please sign in to comment.