zpl: handle suspend from two remaining calls to txg_wait_synced()

* zfs_link: allow tempfile sync to fail if pool suspends

4653e2f7d3 (#17355) allows dmu_tx_assign() to fail if the pool suspends
when failmode=continue, but zfs_link() can fall back to
txg_wait_synced() if it has to wait for a tempfile to be fully created
before continuing, which will block if the pool suspends.

Handle this by requesting an error return if the pool suspends when
failmode=continue, and if that happens, return EIO.

* zfs_clone_range: allow dirty wait to fail if pool suspends

4653e2f7d3 (#17355) allows dmu_tx_assign() to fail if the pool suspends
when failmode=continue, but zfs_clone_range() can fall back to
txg_wait_synced() if it has to wait for a dirty block to be written out,
which will block if the pool suspends.

Handle this by requesting an error return if the pool suspends when
failmode=continue, and if that happens, return EIO.

Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Closes #17413
This commit is contained in:
Rob Norris
2025-06-06 05:38:26 +10:00
committed by GitHub
parent b96f1a4b1f
commit af7d609592
2 changed files with 22 additions and 5 deletions
+11 -2
View File
@@ -3672,8 +3672,17 @@ top:
if (!is_tmpfile && zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
zil_commit(zilog, 0);
if (is_tmpfile && zfsvfs->z_os->os_sync != ZFS_SYNC_DISABLED)
txg_wait_synced(dmu_objset_pool(zfsvfs->z_os), txg);
if (is_tmpfile && zfsvfs->z_os->os_sync != ZFS_SYNC_DISABLED) {
txg_wait_flag_t wait_flags =
spa_get_failmode(dmu_objset_spa(zfsvfs->z_os)) ==
ZIO_FAILURE_MODE_CONTINUE ? TXG_WAIT_SUSPEND : 0;
error = txg_wait_synced_flags(dmu_objset_pool(zfsvfs->z_os),
txg, wait_flags);
if (error != 0) {
ASSERT3U(error, ==, ESHUTDOWN);
error = SET_ERROR(EIO);
}
}
zfs_znode_update_vfs(tdzp);
zfs_znode_update_vfs(szp);