mirror of
https://github.com/openzfs/zfs.git
synced 2025-10-01 02:46:29 +00:00
ZIL: single zil_commit_waiter_done() function to complete a waiter
Just making it easier to not get the locking and broadcast wrong. Sponsored-by: Klara, Inc. Sponsored-by: Wasabi Technology, Inc. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com> Signed-off-by: Rob Norris <rob.norris@klarasystems.com> Closes #17622
This commit is contained in:
parent
92da3e18c8
commit
f562e0f691
@ -154,7 +154,7 @@ typedef struct zil_commit_waiter {
|
|||||||
list_node_t zcw_node; /* linkage in lwb_t:lwb_waiter list */
|
list_node_t zcw_node; /* linkage in lwb_t:lwb_waiter list */
|
||||||
lwb_t *zcw_lwb; /* back pointer to lwb when linked */
|
lwb_t *zcw_lwb; /* back pointer to lwb when linked */
|
||||||
boolean_t zcw_done; /* B_TRUE when "done", else B_FALSE */
|
boolean_t zcw_done; /* B_TRUE when "done", else B_FALSE */
|
||||||
int zcw_zio_error; /* contains the zio io_error value */
|
int zcw_error; /* result to return from zil_commit() */
|
||||||
} zil_commit_waiter_t;
|
} zil_commit_waiter_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1327,10 +1327,12 @@ zil_check_log_chain(dsl_pool_t *dp, dsl_dataset_t *ds, void *tx)
|
|||||||
* zil_commit() is racing with spa_sync().
|
* zil_commit() is racing with spa_sync().
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
zil_commit_waiter_skip(zil_commit_waiter_t *zcw)
|
zil_commit_waiter_done(zil_commit_waiter_t *zcw, int err)
|
||||||
{
|
{
|
||||||
mutex_enter(&zcw->zcw_lock);
|
mutex_enter(&zcw->zcw_lock);
|
||||||
ASSERT3B(zcw->zcw_done, ==, B_FALSE);
|
ASSERT3B(zcw->zcw_done, ==, B_FALSE);
|
||||||
|
zcw->zcw_lwb = NULL;
|
||||||
|
zcw->zcw_error = err;
|
||||||
zcw->zcw_done = B_TRUE;
|
zcw->zcw_done = B_TRUE;
|
||||||
cv_broadcast(&zcw->zcw_cv);
|
cv_broadcast(&zcw->zcw_cv);
|
||||||
mutex_exit(&zcw->zcw_lock);
|
mutex_exit(&zcw->zcw_lock);
|
||||||
@ -1494,10 +1496,6 @@ zil_lwb_flush_vdevs_done(zio_t *zio)
|
|||||||
zil_itx_destroy(itx, 0);
|
zil_itx_destroy(itx, 0);
|
||||||
|
|
||||||
while ((zcw = list_remove_head(&lwb->lwb_waiters)) != NULL) {
|
while ((zcw = list_remove_head(&lwb->lwb_waiters)) != NULL) {
|
||||||
mutex_enter(&zcw->zcw_lock);
|
|
||||||
|
|
||||||
ASSERT3P(zcw->zcw_lwb, ==, lwb);
|
|
||||||
zcw->zcw_lwb = NULL;
|
|
||||||
/*
|
/*
|
||||||
* We expect any ZIO errors from child ZIOs to have been
|
* We expect any ZIO errors from child ZIOs to have been
|
||||||
* propagated "up" to this specific LWB's root ZIO, in
|
* propagated "up" to this specific LWB's root ZIO, in
|
||||||
@ -1512,14 +1510,7 @@ zil_lwb_flush_vdevs_done(zio_t *zio)
|
|||||||
* errors not being handled correctly here. See the
|
* errors not being handled correctly here. See the
|
||||||
* comment above the call to "zio_flush" for details.
|
* comment above the call to "zio_flush" for details.
|
||||||
*/
|
*/
|
||||||
|
zil_commit_waiter_done(zcw, zio->io_error);
|
||||||
zcw->zcw_zio_error = zio->io_error;
|
|
||||||
|
|
||||||
ASSERT3B(zcw->zcw_done, ==, B_FALSE);
|
|
||||||
zcw->zcw_done = B_TRUE;
|
|
||||||
cv_broadcast(&zcw->zcw_cv);
|
|
||||||
|
|
||||||
mutex_exit(&zcw->zcw_lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t txg = lwb->lwb_issued_txg;
|
uint64_t txg = lwb->lwb_issued_txg;
|
||||||
@ -1629,10 +1620,10 @@ zil_lwb_write_done(zio_t *zio)
|
|||||||
* written out.
|
* written out.
|
||||||
*
|
*
|
||||||
* Additionally, we don't perform any further error handling at
|
* Additionally, we don't perform any further error handling at
|
||||||
* this point (e.g. setting "zcw_zio_error" appropriately), as
|
* this point (e.g. setting "zcw_error" appropriately), as we
|
||||||
* we expect that to occur in "zil_lwb_flush_vdevs_done" (thus,
|
* expect that to occur in "zil_lwb_flush_vdevs_done" (thus, we
|
||||||
* we expect any error seen here, to have been propagated to
|
* expect any error seen here, to have been propagated to that
|
||||||
* that function).
|
* function).
|
||||||
*
|
*
|
||||||
* Note that we treat a "crashed" LWB as though it was in error,
|
* Note that we treat a "crashed" LWB as though it was in error,
|
||||||
* even if it did appear to succeed, because we've already
|
* even if it did appear to succeed, because we've already
|
||||||
@ -2566,7 +2557,7 @@ zil_itxg_clean(void *arg)
|
|||||||
* called) we will hit this case.
|
* called) we will hit this case.
|
||||||
*/
|
*/
|
||||||
if (itx->itx_lr.lrc_txtype == TX_COMMIT)
|
if (itx->itx_lr.lrc_txtype == TX_COMMIT)
|
||||||
zil_commit_waiter_skip(itx->itx_private);
|
zil_commit_waiter_done(itx->itx_private, 0);
|
||||||
|
|
||||||
zil_itx_destroy(itx, 0);
|
zil_itx_destroy(itx, 0);
|
||||||
}
|
}
|
||||||
@ -2994,7 +2985,7 @@ zil_prune_commit_list(zilog_t *zilog)
|
|||||||
* never any itx's for it to wait on), so it's
|
* never any itx's for it to wait on), so it's
|
||||||
* safe to skip this waiter and mark it done.
|
* safe to skip this waiter and mark it done.
|
||||||
*/
|
*/
|
||||||
zil_commit_waiter_skip(itx->itx_private);
|
zil_commit_waiter_done(itx->itx_private, 0);
|
||||||
} else {
|
} else {
|
||||||
zil_commit_waiter_link_lwb(itx->itx_private, last_lwb);
|
zil_commit_waiter_link_lwb(itx->itx_private, last_lwb);
|
||||||
}
|
}
|
||||||
@ -3243,7 +3234,7 @@ zil_process_commit_list(zilog_t *zilog, zil_commit_waiter_t *zcw, list_t *ilwbs)
|
|||||||
*/
|
*/
|
||||||
zil_commit_waiter_t *zcw;
|
zil_commit_waiter_t *zcw;
|
||||||
while ((zcw = list_remove_head(&nolwb_waiters)) != NULL)
|
while ((zcw = list_remove_head(&nolwb_waiters)) != NULL)
|
||||||
zil_commit_waiter_skip(zcw);
|
zil_commit_waiter_done(zcw, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* And finally, we have to destroy the itx's that
|
* And finally, we have to destroy the itx's that
|
||||||
@ -3559,7 +3550,7 @@ zil_commit_waiter(zilog_t *zilog, zil_commit_waiter_t *zcw)
|
|||||||
* commit itxs. When this occurs, the commit waiters linked
|
* commit itxs. When this occurs, the commit waiters linked
|
||||||
* off of these commit itxs will not be committed to an
|
* off of these commit itxs will not be committed to an
|
||||||
* lwb. Additionally, these commit waiters will not be
|
* lwb. Additionally, these commit waiters will not be
|
||||||
* marked done until zil_commit_waiter_skip() is called via
|
* marked done until zil_commit_waiter_done() is called via
|
||||||
* zil_itxg_clean().
|
* zil_itxg_clean().
|
||||||
*
|
*
|
||||||
* Thus, it's possible for this commit waiter (i.e. the
|
* Thus, it's possible for this commit waiter (i.e. the
|
||||||
@ -3637,7 +3628,7 @@ zil_alloc_commit_waiter(void)
|
|||||||
list_link_init(&zcw->zcw_node);
|
list_link_init(&zcw->zcw_node);
|
||||||
zcw->zcw_lwb = NULL;
|
zcw->zcw_lwb = NULL;
|
||||||
zcw->zcw_done = B_FALSE;
|
zcw->zcw_done = B_FALSE;
|
||||||
zcw->zcw_zio_error = 0;
|
zcw->zcw_error = 0;
|
||||||
|
|
||||||
return (zcw);
|
return (zcw);
|
||||||
}
|
}
|
||||||
@ -3752,7 +3743,7 @@ zil_crash(zilog_t *zilog)
|
|||||||
while ((zcw = list_remove_head(&lwb->lwb_waiters)) != NULL) {
|
while ((zcw = list_remove_head(&lwb->lwb_waiters)) != NULL) {
|
||||||
mutex_enter(&zcw->zcw_lock);
|
mutex_enter(&zcw->zcw_lock);
|
||||||
zcw->zcw_lwb = NULL;
|
zcw->zcw_lwb = NULL;
|
||||||
zcw->zcw_zio_error = EIO;
|
zcw->zcw_error = EIO;
|
||||||
zcw->zcw_done = B_TRUE;
|
zcw->zcw_done = B_TRUE;
|
||||||
cv_broadcast(&zcw->zcw_cv);
|
cv_broadcast(&zcw->zcw_cv);
|
||||||
mutex_exit(&zcw->zcw_lock);
|
mutex_exit(&zcw->zcw_lock);
|
||||||
@ -4030,7 +4021,7 @@ zil_commit_impl(zilog_t *zilog, uint64_t foid)
|
|||||||
zil_commit_waiter(zilog, zcw);
|
zil_commit_waiter(zilog, zcw);
|
||||||
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
if (zcw->zcw_zio_error != 0) {
|
if (zcw->zcw_error != 0) {
|
||||||
/*
|
/*
|
||||||
* If there was an error writing out the ZIL blocks that
|
* If there was an error writing out the ZIL blocks that
|
||||||
* this thread is waiting on, then we fallback to
|
* this thread is waiting on, then we fallback to
|
||||||
|
Loading…
Reference in New Issue
Block a user