ZIL: add zil_commit_flags() to make honouring failmode= optional

The vast majority of calls to zil_commit() follow VFS ops, and should
honour the failmode= setting - either wait for sync, or return error.
Some calls however are part of a larger syncing op, and shouldn't ever
block if something goes wrong.

To allow this, we introduce zil_commit_flags(), with a flag
ZIL_COMMIT_FAILMODE to indicate whether or not the pool failmode should
be honoured. zil_commit() is now a wrapper that always sets this flag,
but any caller wanting a different behaviour can request ZIL_COMMIT_NOW
instead to have the call return failure if the pool suspends, regardless
of the failmode= setting.

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 #17398
This commit is contained in:
Rob Norris
2025-06-17 11:33:06 +10:00
committed by Brian Behlendorf
parent 72602f6ad9
commit 391e85f519
2 changed files with 35 additions and 3 deletions
+12 -2
View File
@@ -3878,6 +3878,12 @@ static int zil_commit_impl(zilog_t *zilog, uint64_t foid);
int
zil_commit(zilog_t *zilog, uint64_t foid)
{
return (zil_commit_flags(zilog, foid, ZIL_COMMIT_FAILMODE));
}
int
zil_commit_flags(zilog_t *zilog, uint64_t foid, zil_commit_flag_t flags)
{
/*
* We should never attempt to call zil_commit on a snapshot for
@@ -3955,7 +3961,11 @@ out:
*/
ASSERT3U(err, ==, ESHUTDOWN);
if (spa_get_failmode(zilog->zl_spa) == ZIO_FAILURE_MODE_CONTINUE)
/*
* Return error if failmode=continue or caller will handle directly.
*/
if (!(flags & ZIL_COMMIT_FAILMODE) ||
spa_get_failmode(zilog->zl_spa) == ZIO_FAILURE_MODE_CONTINUE)
return (SET_ERROR(EIO));
/*
@@ -4321,7 +4331,7 @@ zil_close(zilog_t *zilog)
uint64_t txg;
if (!dmu_objset_is_snapshot(zilog->zl_os)) {
if (zil_commit(zilog, 0) != 0)
if (zil_commit_flags(zilog, 0, ZIL_COMMIT_NOW) != 0)
txg_wait_synced(zilog->zl_dmu_pool, 0);
} else {
ASSERT(list_is_empty(&zilog->zl_lwb_list));