mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2025-06-25 02:28:01 +03:00
Clarify and restrict dmu_tx_assign() errors
There are three possible cases where dmu_tx_assign() may encounter a fatal error. When there is a true lack of free space (ENOSPC), when there is a lack of quota space (EDQUOT), or when data required to perform the transaction cannot be read from disk (EIO). See the dmu_tx_check_ioerr() function for additional details of on the motivation for check for I/O error early. Prior to this change dmu_tx_assign() would return the contents of tx->tx_err which covered a wide range of possible error codes (EIO, ECKSUM, ESRCH, etc). In practice, none of the callers could do anything useful with this level of detail and simply returned the error. Therefore, this change converts all tx->tx_err errors to EIO, adds ASSERTs to dmu_tx_assign() to cover the only possible errors, and clarifies the function comment to include EIO as a possible fatal error. Reviewed-by: Alexander Motin <mav@FreeBSD.org> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Brian D Behlendorf <behlendo@slag12.llnl.gov> Closes #17463
This commit is contained in:
parent
8170eb6ebc
commit
48ce292ea0
@ -1816,7 +1816,7 @@ ztest_zd_fini(ztest_ds_t *zd)
|
|||||||
(ztest_random(10) == 0 ? DMU_TX_NOWAIT : DMU_TX_WAIT)
|
(ztest_random(10) == 0 ? DMU_TX_NOWAIT : DMU_TX_WAIT)
|
||||||
|
|
||||||
static uint64_t
|
static uint64_t
|
||||||
ztest_tx_assign(dmu_tx_t *tx, uint64_t txg_how, const char *tag)
|
ztest_tx_assign(dmu_tx_t *tx, dmu_tx_flag_t txg_how, const char *tag)
|
||||||
{
|
{
|
||||||
uint64_t txg;
|
uint64_t txg;
|
||||||
int error;
|
int error;
|
||||||
@ -1829,9 +1829,10 @@ ztest_tx_assign(dmu_tx_t *tx, uint64_t txg_how, const char *tag)
|
|||||||
if (error == ERESTART) {
|
if (error == ERESTART) {
|
||||||
ASSERT3U(txg_how, ==, DMU_TX_NOWAIT);
|
ASSERT3U(txg_how, ==, DMU_TX_NOWAIT);
|
||||||
dmu_tx_wait(tx);
|
dmu_tx_wait(tx);
|
||||||
} else {
|
} else if (error == ENOSPC) {
|
||||||
ASSERT3U(error, ==, ENOSPC);
|
|
||||||
ztest_record_enospc(tag);
|
ztest_record_enospc(tag);
|
||||||
|
} else {
|
||||||
|
ASSERT(error == EDQUOT || error == EIO);
|
||||||
}
|
}
|
||||||
dmu_tx_abort(tx);
|
dmu_tx_abort(tx);
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -1054,7 +1054,7 @@ dmu_tx_try_assign(dmu_tx_t *tx)
|
|||||||
|
|
||||||
if (tx->tx_err) {
|
if (tx->tx_err) {
|
||||||
DMU_TX_STAT_BUMP(dmu_tx_error);
|
DMU_TX_STAT_BUMP(dmu_tx_error);
|
||||||
return (tx->tx_err);
|
return (SET_ERROR(EIO));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spa_suspended(spa)) {
|
if (spa_suspended(spa)) {
|
||||||
@ -1190,7 +1190,8 @@ dmu_tx_unassign(dmu_tx_t *tx)
|
|||||||
* If DMU_TX_WAIT is set and the currently open txg is full, this function
|
* If DMU_TX_WAIT is set and the currently open txg is full, this function
|
||||||
* will wait until there's a new txg. This should be used when no locks
|
* will wait until there's a new txg. This should be used when no locks
|
||||||
* are being held. With this bit set, this function will only fail if
|
* are being held. With this bit set, this function will only fail if
|
||||||
* we're truly out of space (or over quota).
|
* we're truly out of space (ENOSPC), over quota (EDQUOT), or required
|
||||||
|
* data for the transaction could not be read from disk (EIO).
|
||||||
*
|
*
|
||||||
* If DMU_TX_WAIT is *not* set and we can't assign into the currently open
|
* If DMU_TX_WAIT is *not* set and we can't assign into the currently open
|
||||||
* txg without blocking, this function will return immediately with
|
* txg without blocking, this function will return immediately with
|
||||||
@ -1279,8 +1280,11 @@ dmu_tx_assign(dmu_tx_t *tx, dmu_tx_flag_t flags)
|
|||||||
* Return unless we decided to retry, or the caller does not
|
* Return unless we decided to retry, or the caller does not
|
||||||
* want to block.
|
* want to block.
|
||||||
*/
|
*/
|
||||||
if (err != ERESTART || !(flags & DMU_TX_WAIT))
|
if (err != ERESTART || !(flags & DMU_TX_WAIT)) {
|
||||||
|
ASSERT(err == EDQUOT || err == ENOSPC ||
|
||||||
|
err == ERESTART || err == EIO);
|
||||||
return (err);
|
return (err);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wait until there's room in this txg, or until it's been
|
* Wait until there's room in this txg, or until it's been
|
||||||
|
@ -1450,6 +1450,8 @@ dsl_dir_tempreserve_space(dsl_dir_t *dd, uint64_t lsize, uint64_t asize,
|
|||||||
MSEC2NSEC(10), MSEC2NSEC(10));
|
MSEC2NSEC(10), MSEC2NSEC(10));
|
||||||
err = SET_ERROR(ERESTART);
|
err = SET_ERROR(ERESTART);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ASSERT3U(err, ==, ERESTART);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err == 0) {
|
if (err == 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user