Skip to content

Commit ebbbd5c

Browse files
robnspauka
authored andcommitted
zpl: handle suspend from two remaining calls to txg_wait_synced()
* zfs_link: allow tempfile sync to fail if pool suspends 4653e2f (openzfs#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 4653e2f (openzfs#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 openzfs#17413
1 parent a0de0fc commit ebbbd5c

2 files changed

Lines changed: 22 additions & 5 deletions

File tree

module/os/linux/zfs/zfs_vnops_os.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3672,8 +3672,17 @@ zfs_link(znode_t *tdzp, znode_t *szp, char *name, cred_t *cr,
36723672
if (!is_tmpfile && zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
36733673
zil_commit(zilog, 0);
36743674

3675-
if (is_tmpfile && zfsvfs->z_os->os_sync != ZFS_SYNC_DISABLED)
3676-
txg_wait_synced(dmu_objset_pool(zfsvfs->z_os), txg);
3675+
if (is_tmpfile && zfsvfs->z_os->os_sync != ZFS_SYNC_DISABLED) {
3676+
txg_wait_flag_t wait_flags =
3677+
spa_get_failmode(dmu_objset_spa(zfsvfs->z_os)) ==
3678+
ZIO_FAILURE_MODE_CONTINUE ? TXG_WAIT_SUSPEND : 0;
3679+
error = txg_wait_synced_flags(dmu_objset_pool(zfsvfs->z_os),
3680+
txg, wait_flags);
3681+
if (error != 0) {
3682+
ASSERT3U(error, ==, ESHUTDOWN);
3683+
error = SET_ERROR(EIO);
3684+
}
3685+
}
36773686

36783687
zfs_znode_update_vfs(tdzp);
36793688
zfs_znode_update_vfs(szp);

module/zfs/zfs_vnops.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1813,9 +1813,17 @@ zfs_clone_range(znode_t *inzp, uint64_t *inoffp, znode_t *outzp,
18131813
* fallback, or wait for the next TXG and check again.
18141814
*/
18151815
if (error == EAGAIN && zfs_bclone_wait_dirty) {
1816-
txg_wait_synced(dmu_objset_pool(inos),
1817-
last_synced_txg + 1);
1818-
continue;
1816+
txg_wait_flag_t wait_flags =
1817+
spa_get_failmode(dmu_objset_spa(inos)) ==
1818+
ZIO_FAILURE_MODE_CONTINUE ?
1819+
TXG_WAIT_SUSPEND : 0;
1820+
error = txg_wait_synced_flags(
1821+
dmu_objset_pool(inos), last_synced_txg + 1,
1822+
wait_flags);
1823+
if (error == 0)
1824+
continue;
1825+
ASSERT3U(error, ==, ESHUTDOWN);
1826+
error = SET_ERROR(EIO);
18191827
}
18201828

18211829
break;

0 commit comments

Comments
 (0)