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
+23 -1
View File
@@ -581,6 +581,25 @@ typedef struct zil_sums {
#define ZIL_STAT_BUMP(zil, stat) \
ZIL_STAT_INCR(zil, stat, 1);
/*
* Flags for zil_commit_flags(). zil_commit() is a shortcut for
* zil_commit_flags(ZIL_COMMIT_FAILMODE), which is the most common use.
*/
typedef enum {
/*
* Try to commit the ZIL. If it fails, fall back to txg_wait_synced().
* If that fails, return EIO.
*/
ZIL_COMMIT_NOW = 0,
/*
* Like ZIL_COMMIT_NOW, but if the ZIL commit fails because the pool
* suspended, act according to the pool's failmode= setting (wait for
* the pool to resume, or return EIO).
*/
ZIL_COMMIT_FAILMODE = (1 << 1),
} zil_commit_flag_t;
typedef int zil_parse_blk_func_t(zilog_t *zilog, const blkptr_t *bp, void *arg,
uint64_t txg);
typedef int zil_parse_lr_func_t(zilog_t *zilog, const lr_t *lr, void *arg,
@@ -614,9 +633,12 @@ extern void zil_itx_destroy(itx_t *itx, int err);
extern void zil_itx_assign(zilog_t *zilog, itx_t *itx, dmu_tx_t *tx);
extern void zil_async_to_sync(zilog_t *zilog, uint64_t oid);
extern int __must_check zil_commit(zilog_t *zilog, uint64_t oid);
extern void zil_remove_async(zilog_t *zilog, uint64_t oid);
extern int zil_commit_flags(zilog_t *zilog, uint64_t oid,
zil_commit_flag_t flags);
extern int __must_check zil_commit(zilog_t *zilog, uint64_t oid);
extern int zil_reset(const char *osname, void *txarg);
extern int zil_claim(struct dsl_pool *dp,
struct dsl_dataset *ds, void *txarg);