mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +03:00
ZIL: allow zil_commit() to fail with error
This changes zil_commit() to have an int return, and updates all callers to check it. There are no corresponding internal changes yet; it will always return 0. Since zil_commit() is an indication that the caller _really_ wants the associated data to be durability stored, I've annotated it with the __warn_unused_result__ compiler attribute (via __must_check), to emit a warning if it's ever ussd without doing something with the return code. I hope this will mean we never misuse it in the future. 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
1f8c39ddb2
commit
967b15b888
@@ -288,10 +288,10 @@ zfs_sync(struct super_block *sb, int wait, cred_t *cr)
|
||||
return (SET_ERROR(EIO));
|
||||
}
|
||||
|
||||
zil_commit(zfsvfs->z_log, 0);
|
||||
err = zil_commit(zfsvfs->z_log, 0);
|
||||
zfs_exit(zfsvfs, FTAG);
|
||||
|
||||
return (0);
|
||||
return (err);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -841,8 +841,8 @@ out:
|
||||
*zpp = zp;
|
||||
}
|
||||
|
||||
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
|
||||
zil_commit(zilog, 0);
|
||||
if (error == 0 && zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
|
||||
error = zil_commit(zilog, 0);
|
||||
|
||||
zfs_exit(zfsvfs, FTAG);
|
||||
return (error);
|
||||
@@ -1203,8 +1203,8 @@ out:
|
||||
zfs_zrele_async(xzp);
|
||||
}
|
||||
|
||||
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
|
||||
zil_commit(zilog, 0);
|
||||
if (error == 0 && zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
|
||||
error = zil_commit(zilog, 0);
|
||||
|
||||
zfs_exit(zfsvfs, FTAG);
|
||||
return (error);
|
||||
@@ -1392,14 +1392,15 @@ out:
|
||||
|
||||
zfs_dirent_unlock(dl);
|
||||
|
||||
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
|
||||
zil_commit(zilog, 0);
|
||||
|
||||
if (error != 0) {
|
||||
zrele(zp);
|
||||
} else {
|
||||
zfs_znode_update_vfs(dzp);
|
||||
zfs_znode_update_vfs(zp);
|
||||
|
||||
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
|
||||
error = zil_commit(zilog, 0);
|
||||
|
||||
}
|
||||
zfs_exit(zfsvfs, FTAG);
|
||||
return (error);
|
||||
@@ -1528,8 +1529,8 @@ out:
|
||||
zfs_znode_update_vfs(zp);
|
||||
zrele(zp);
|
||||
|
||||
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
|
||||
zil_commit(zilog, 0);
|
||||
if (error == 0 && zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
|
||||
error = zil_commit(zilog, 0);
|
||||
|
||||
zfs_exit(zfsvfs, FTAG);
|
||||
return (error);
|
||||
@@ -2630,8 +2631,8 @@ out:
|
||||
}
|
||||
|
||||
out2:
|
||||
if (os->os_sync == ZFS_SYNC_ALWAYS)
|
||||
zil_commit(zilog, 0);
|
||||
if (err == 0 && os->os_sync == ZFS_SYNC_ALWAYS)
|
||||
err = zil_commit(zilog, 0);
|
||||
|
||||
out3:
|
||||
kmem_free(xattr_bulk, sizeof (sa_bulk_attr_t) * bulks);
|
||||
@@ -3235,8 +3236,8 @@ out:
|
||||
zfs_dirent_unlock(sdl);
|
||||
zfs_dirent_unlock(tdl);
|
||||
|
||||
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
|
||||
zil_commit(zilog, 0);
|
||||
if (error == 0 && zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
|
||||
error = zil_commit(zilog, 0);
|
||||
|
||||
zfs_exit(zfsvfs, FTAG);
|
||||
return (error);
|
||||
@@ -3436,7 +3437,7 @@ top:
|
||||
*zpp = zp;
|
||||
|
||||
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
|
||||
zil_commit(zilog, 0);
|
||||
error = zil_commit(zilog, 0);
|
||||
} else {
|
||||
zrele(zp);
|
||||
}
|
||||
@@ -3670,18 +3671,20 @@ top:
|
||||
|
||||
zfs_dirent_unlock(dl);
|
||||
|
||||
if (!is_tmpfile && zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
|
||||
zil_commit(zilog, 0);
|
||||
if (error == 0) {
|
||||
if (!is_tmpfile && zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
|
||||
error = zil_commit(zilog, 0);
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3939,8 +3942,13 @@ zfs_putpage(struct inode *ip, struct page *pp, struct writeback_control *wbc,
|
||||
|
||||
zfs_rangelock_exit(lr);
|
||||
|
||||
if (need_commit)
|
||||
zil_commit(zfsvfs->z_log, zp->z_id);
|
||||
if (need_commit) {
|
||||
err = zil_commit(zfsvfs->z_log, zp->z_id);
|
||||
if (err != 0) {
|
||||
zfs_exit(zfsvfs, FTAG);
|
||||
return (err);
|
||||
}
|
||||
}
|
||||
|
||||
dataset_kstats_update_write_kstats(&zfsvfs->z_kstat, pglen);
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Lawrence Livermore National Security, LLC.
|
||||
* Copyright (c) 2015 by Chunwei Chen. All rights reserved.
|
||||
* Copyright (c) 2025, Klara, Inc.
|
||||
*/
|
||||
|
||||
|
||||
@@ -495,9 +496,18 @@ zpl_writepages(struct address_space *mapping, struct writeback_control *wbc)
|
||||
if ((result = zpl_enter_verify_zp(zfsvfs, zp, FTAG)) != 0)
|
||||
return (result);
|
||||
if (zfsvfs->z_log != NULL)
|
||||
zil_commit(zfsvfs->z_log, zp->z_id);
|
||||
result = -zil_commit(zfsvfs->z_log, zp->z_id);
|
||||
zpl_exit(zfsvfs, FTAG);
|
||||
|
||||
/*
|
||||
* If zil_commit() failed, it's unclear what state things
|
||||
* are currently in. putpage() has written back out what
|
||||
* it can to the DMU, but it may not be on disk. We have
|
||||
* little choice but to escape.
|
||||
*/
|
||||
if (result != 0)
|
||||
return (result);
|
||||
|
||||
/*
|
||||
* We need to call write_cache_pages() again (we can't just
|
||||
* return after the commit) because the previous call in
|
||||
|
||||
@@ -208,8 +208,14 @@ zvol_write(zv_request_t *zvr)
|
||||
disk = zv->zv_zso->zvo_disk;
|
||||
|
||||
/* bio marked as FLUSH need to flush before write */
|
||||
if (io_is_flush(bio, rq))
|
||||
zil_commit(zv->zv_zilog, ZVOL_OBJ);
|
||||
if (io_is_flush(bio, rq)) {
|
||||
error = zil_commit(zv->zv_zilog, ZVOL_OBJ);
|
||||
if (error != 0) {
|
||||
rw_exit(&zv->zv_suspend_lock);
|
||||
zvol_end_io(bio, rq, -error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Some requests are just for flush and nothing else. */
|
||||
if (io_size(bio, rq) == 0) {
|
||||
@@ -273,8 +279,8 @@ zvol_write(zv_request_t *zvr)
|
||||
dataset_kstats_update_write_kstats(&zv->zv_kstat, nwritten);
|
||||
task_io_account_write(nwritten);
|
||||
|
||||
if (sync)
|
||||
zil_commit(zv->zv_zilog, ZVOL_OBJ);
|
||||
if (error == 0 && sync)
|
||||
error = zil_commit(zv->zv_zilog, ZVOL_OBJ);
|
||||
|
||||
rw_exit(&zv->zv_suspend_lock);
|
||||
|
||||
@@ -361,7 +367,7 @@ zvol_discard(zv_request_t *zvr)
|
||||
zfs_rangelock_exit(lr);
|
||||
|
||||
if (error == 0 && sync)
|
||||
zil_commit(zv->zv_zilog, ZVOL_OBJ);
|
||||
error = zil_commit(zv->zv_zilog, ZVOL_OBJ);
|
||||
|
||||
unlock:
|
||||
rw_exit(&zv->zv_suspend_lock);
|
||||
|
||||
Reference in New Issue
Block a user