mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-01-14 17:22:05 +03:00
ZIL: pass commit errors back to ITX callbacks
ITX callbacks are used to signal that something can be cleaned up after a itx is committed. Presently that's only used when syncing out mapped pages (msync()) to mark dirty pages clean. This extends the callback interface so it can be passed an error, and take a different cleanup action if necessary. 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:
parent
967b15b888
commit
99a5f5d1ba
@ -1995,7 +1995,7 @@ ztest_log_write(ztest_ds_t *zd, dmu_tx_t *tx, lr_write_t *lr)
|
||||
dmu_read(zd->zd_os, lr->lr_foid, lr->lr_offset, lr->lr_length,
|
||||
((lr_write_t *)&itx->itx_lr) + 1, DMU_READ_NO_PREFETCH |
|
||||
DMU_KEEP_CACHING) != 0) {
|
||||
zil_itx_destroy(itx);
|
||||
zil_itx_destroy(itx, 0);
|
||||
itx = zil_itx_create(TX_WRITE, sizeof (*lr));
|
||||
write_state = WR_NEED_COPY;
|
||||
}
|
||||
|
||||
@ -456,7 +456,7 @@ typedef enum {
|
||||
WR_NUM_STATES /* number of states */
|
||||
} itx_wr_state_t;
|
||||
|
||||
typedef void (*zil_callback_t)(void *data);
|
||||
typedef void (*zil_callback_t)(void *data, int err);
|
||||
|
||||
typedef struct itx {
|
||||
list_node_t itx_node; /* linkage on zl_itx_list */
|
||||
@ -606,7 +606,7 @@ extern boolean_t zil_destroy(zilog_t *zilog, boolean_t keep_first);
|
||||
extern void zil_destroy_sync(zilog_t *zilog, dmu_tx_t *tx);
|
||||
|
||||
extern itx_t *zil_itx_create(uint64_t txtype, size_t lrsize);
|
||||
extern void zil_itx_destroy(itx_t *itx);
|
||||
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);
|
||||
|
||||
@ -4312,8 +4312,9 @@ typedef struct {
|
||||
} putpage_commit_arg_t;
|
||||
|
||||
static void
|
||||
zfs_putpage_commit_cb(void *arg)
|
||||
zfs_putpage_commit_cb(void *arg, int err)
|
||||
{
|
||||
(void) err;
|
||||
putpage_commit_arg_t *pca = arg;
|
||||
vm_object_t object = pca->pca_pages[0]->object;
|
||||
|
||||
|
||||
@ -3697,6 +3697,7 @@ top:
|
||||
static void
|
||||
zfs_putpage_commit_cb(void *arg)
|
||||
{
|
||||
(void) err;
|
||||
struct page *pp = arg;
|
||||
|
||||
ClearPageError(pp);
|
||||
|
||||
@ -620,7 +620,7 @@ zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
|
||||
if (zil_replaying(zilog, tx) || zp->z_unlinked ||
|
||||
zfs_xattr_owner_unlinked(zp)) {
|
||||
if (callback != NULL)
|
||||
callback(callback_data);
|
||||
callback(callback_data, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -663,7 +663,7 @@ zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
|
||||
DMU_KEEP_CACHING);
|
||||
DB_DNODE_EXIT(db);
|
||||
if (err != 0) {
|
||||
zil_itx_destroy(itx);
|
||||
zil_itx_destroy(itx, 0);
|
||||
itx = zil_itx_create(txtype, sizeof (*lr));
|
||||
lr = (lr_write_t *)&itx->itx_lr;
|
||||
wr_state = WR_NEED_COPY;
|
||||
|
||||
@ -1482,7 +1482,7 @@ zil_lwb_flush_vdevs_done(zio_t *zio)
|
||||
}
|
||||
|
||||
while ((itx = list_remove_head(&lwb->lwb_itxs)) != NULL)
|
||||
zil_itx_destroy(itx);
|
||||
zil_itx_destroy(itx, 0);
|
||||
|
||||
while ((zcw = list_remove_head(&lwb->lwb_waiters)) != NULL) {
|
||||
mutex_enter(&zcw->zcw_lock);
|
||||
@ -2468,7 +2468,7 @@ zil_itx_clone(itx_t *oitx)
|
||||
}
|
||||
|
||||
void
|
||||
zil_itx_destroy(itx_t *itx)
|
||||
zil_itx_destroy(itx_t *itx, int err)
|
||||
{
|
||||
ASSERT3U(itx->itx_size, >=, sizeof (itx_t));
|
||||
ASSERT3U(itx->itx_lr.lrc_reclen, ==,
|
||||
@ -2477,7 +2477,7 @@ zil_itx_destroy(itx_t *itx)
|
||||
IMPLY(itx->itx_callback != NULL, itx->itx_lr.lrc_txtype != TX_COMMIT);
|
||||
|
||||
if (itx->itx_callback != NULL)
|
||||
itx->itx_callback(itx->itx_callback_data);
|
||||
itx->itx_callback(itx->itx_callback_data, err);
|
||||
|
||||
zio_data_buf_free(itx, itx->itx_size);
|
||||
}
|
||||
@ -2520,7 +2520,7 @@ zil_itxg_clean(void *arg)
|
||||
if (itx->itx_lr.lrc_txtype == TX_COMMIT)
|
||||
zil_commit_waiter_skip(itx->itx_private);
|
||||
|
||||
zil_itx_destroy(itx);
|
||||
zil_itx_destroy(itx, 0);
|
||||
}
|
||||
|
||||
cookie = NULL;
|
||||
@ -2530,7 +2530,7 @@ zil_itxg_clean(void *arg)
|
||||
while ((itx = list_remove_head(list)) != NULL) {
|
||||
/* commit itxs should never be on the async lists. */
|
||||
ASSERT3U(itx->itx_lr.lrc_txtype, !=, TX_COMMIT);
|
||||
zil_itx_destroy(itx);
|
||||
zil_itx_destroy(itx, 0);
|
||||
}
|
||||
list_destroy(list);
|
||||
kmem_free(ian, sizeof (itx_async_node_t));
|
||||
@ -2592,7 +2592,7 @@ zil_remove_async(zilog_t *zilog, uint64_t oid)
|
||||
while ((itx = list_remove_head(&clean_list)) != NULL) {
|
||||
/* commit itxs should never be on the async lists. */
|
||||
ASSERT3U(itx->itx_lr.lrc_txtype, !=, TX_COMMIT);
|
||||
zil_itx_destroy(itx);
|
||||
zil_itx_destroy(itx, 0);
|
||||
}
|
||||
list_destroy(&clean_list);
|
||||
}
|
||||
@ -2883,7 +2883,7 @@ zil_prune_commit_list(zilog_t *zilog)
|
||||
mutex_exit(&zilog->zl_lock);
|
||||
|
||||
list_remove(&zilog->zl_itx_commit_list, itx);
|
||||
zil_itx_destroy(itx);
|
||||
zil_itx_destroy(itx, 0);
|
||||
}
|
||||
|
||||
IMPLY(itx != NULL, itx->itx_lr.lrc_txtype != TX_COMMIT);
|
||||
@ -3082,7 +3082,7 @@ zil_process_commit_list(zilog_t *zilog, zil_commit_waiter_t *zcw, list_t *ilwbs)
|
||||
} else {
|
||||
ASSERT3S(lrc->lrc_txtype, !=, TX_COMMIT);
|
||||
zilog->zl_cur_left -= zil_itx_full_size(itx);
|
||||
zil_itx_destroy(itx);
|
||||
zil_itx_destroy(itx, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3113,7 +3113,7 @@ zil_process_commit_list(zilog_t *zilog, zil_commit_waiter_t *zcw, list_t *ilwbs)
|
||||
* the itx's callback if one exists for the itx.
|
||||
*/
|
||||
while ((itx = list_remove_head(&nolwb_itxs)) != NULL)
|
||||
zil_itx_destroy(itx);
|
||||
zil_itx_destroy(itx, 0);
|
||||
} else {
|
||||
ASSERT(list_is_empty(&nolwb_waiters));
|
||||
ASSERT3P(lwb, !=, NULL);
|
||||
|
||||
@ -898,7 +898,7 @@ zvol_log_write(zvol_state_t *zv, dmu_tx_t *tx, uint64_t offset,
|
||||
if (wr_state == WR_COPIED &&
|
||||
dmu_read_by_dnode(zv->zv_dn, offset, len, lr + 1,
|
||||
DMU_READ_NO_PREFETCH | DMU_KEEP_CACHING) != 0) {
|
||||
zil_itx_destroy(itx);
|
||||
zil_itx_destroy(itx, 0);
|
||||
itx = zil_itx_create(TX_WRITE, sizeof (*lr));
|
||||
lr = (lr_write_t *)&itx->itx_lr;
|
||||
wr_state = WR_NEED_COPY;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user