mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +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:
committed by
Brian Behlendorf
parent
967b15b888
commit
99a5f5d1ba
@@ -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;
|
||||
|
||||
+9
-9
@@ -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);
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user