Make TX abort after assign safer

It is not right, but there are few examples when TX is aborted
after being assigned in case of error.  To handle it better on
production systems add extra cleanup steps.

While here, replace couple dmu_tx_abort() in simple cases.

Reviewed-by: Rob Norris <robn@despairlabs.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Igor Kozhukhov <igor@dilos.org>
Signed-off-by:	Alexander Motin <mav@FreeBSD.org>
Sponsored by:	iXsystems, Inc.
Closes #17438
This commit is contained in:
Alexander Motin 2025-06-10 12:30:06 -04:00 committed by Brian Behlendorf
parent 4c8d0471fa
commit 3897e86bd1
2 changed files with 11 additions and 2 deletions

View File

@ -1323,6 +1323,7 @@ dmu_tx_destroy(dmu_tx_t *tx)
void
dmu_tx_commit(dmu_tx_t *tx)
{
/* This function should only be used on assigned transactions. */
ASSERT(tx->tx_txg != 0);
/*
@ -1361,7 +1362,12 @@ dmu_tx_commit(dmu_tx_t *tx)
void
dmu_tx_abort(dmu_tx_t *tx)
{
ASSERT(tx->tx_txg == 0);
/* This function should not be used on assigned transactions. */
ASSERT0(tx->tx_txg);
/* Should not be needed, but better be safe than sorry. */
if (tx->tx_tempreserve_cookie)
dsl_dir_tempreserve_clear(tx->tx_tempreserve_cookie, tx);
/*
* Call any registered callbacks with an error code.
@ -1369,6 +1375,9 @@ dmu_tx_abort(dmu_tx_t *tx)
if (!list_is_empty(&tx->tx_callbacks))
dmu_tx_do_callbacks(&tx->tx_callbacks, SET_ERROR(ECANCELED));
/* Should not be needed, but better be safe than sorry. */
dmu_tx_unassign(tx);
dmu_tx_destroy(tx);
}

View File

@ -1681,7 +1681,7 @@ zfs_clone_range(znode_t *inzp, uint64_t *inoffp, znode_t *outzp,
*/
if (inblksz != outzp->z_blksz) {
error = SET_ERROR(EINVAL);
dmu_tx_abort(tx);
dmu_tx_commit(tx);
break;
}