ZIL: Fix another use-after-free.
lwb->lwb_issued_txg can not be accessed after lwb_state is set to
LWB_STATE_FLUSH_DONE and zl_lock is dropped, since the lwb may be
freed by zil_sync(). We must save the txg number before that.
This is similar to the 55b1842f92
, but as I see the bug is not new.
It existed for quite a while, just was not triggered due to smaller
race window.
Reviewed-by: Allan Jude <allan@klarasystems.com>
Reviewed-by: Brian Atkinson <batkinson@lanl.gov>
Signed-off-by: Alexander Motin <mav@FreeBSD.org>
Sponsored by: iXsystems, Inc.
Closes #14988
Closes #14999
This commit is contained in:
parent
b0cbc1aa9a
commit
a9d6b0690b
|
@ -1425,6 +1425,7 @@ zil_lwb_flush_vdevs_done(zio_t *zio)
|
||||||
|
|
||||||
list_move_tail(&itxs, &lwb->lwb_itxs);
|
list_move_tail(&itxs, &lwb->lwb_itxs);
|
||||||
list_move_tail(&waiters, &lwb->lwb_waiters);
|
list_move_tail(&waiters, &lwb->lwb_waiters);
|
||||||
|
txg = lwb->lwb_issued_txg;
|
||||||
|
|
||||||
ASSERT3S(lwb->lwb_state, ==, LWB_STATE_WRITE_DONE);
|
ASSERT3S(lwb->lwb_state, ==, LWB_STATE_WRITE_DONE);
|
||||||
lwb->lwb_state = LWB_STATE_FLUSH_DONE;
|
lwb->lwb_state = LWB_STATE_FLUSH_DONE;
|
||||||
|
@ -1465,7 +1466,6 @@ zil_lwb_flush_vdevs_done(zio_t *zio)
|
||||||
list_destroy(&waiters);
|
list_destroy(&waiters);
|
||||||
|
|
||||||
mutex_enter(&zilog->zl_lwb_io_lock);
|
mutex_enter(&zilog->zl_lwb_io_lock);
|
||||||
txg = lwb->lwb_issued_txg;
|
|
||||||
ASSERT3U(zilog->zl_lwb_inflight[txg & TXG_MASK], >, 0);
|
ASSERT3U(zilog->zl_lwb_inflight[txg & TXG_MASK], >, 0);
|
||||||
zilog->zl_lwb_inflight[txg & TXG_MASK]--;
|
zilog->zl_lwb_inflight[txg & TXG_MASK]--;
|
||||||
if (zilog->zl_lwb_inflight[txg & TXG_MASK] == 0)
|
if (zilog->zl_lwb_inflight[txg & TXG_MASK] == 0)
|
||||||
|
|
Loading…
Reference in New Issue