linux: reject syncing ops if the filesystem is unmounting

The kernel can call these during unmount, so we have to handle them
directly to prevent any further IO being issued.

zfs_fsync reorganised slightly to not set up zfs_fsyncer_key until after
the teardown lock is acquired, just in case we don't get it.

Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
(cherry picked from commit 900c26570ddcdd1d3ca135e6aee5df6456f6bfd6)
This commit is contained in:
Rob Norris 2023-05-04 22:11:20 +10:00 committed by Geoff Amey
parent 7e4a9cbaee
commit 3aea149bf8
3 changed files with 13 additions and 8 deletions

View File

@ -275,7 +275,8 @@ zfs_sync(struct super_block *sb, int wait, cred_t *cr)
*/
dsl_pool_t *dp;
ZFS_ENTER(zfsvfs);
ZFS_ENTER_UNMOUNTOK(zfsvfs);
dp = dmu_objset_pool(zfsvfs->z_os);
/*

View File

@ -3665,7 +3665,7 @@ zfs_dirty_inode(struct inode *ip, int flags)
if (zfs_is_readonly(zfsvfs) || dmu_objset_is_snapshot(zfsvfs->z_os))
return (0);
ZFS_ENTER(zfsvfs);
ZFS_ENTER_UNMOUNTOK(zfsvfs);
ZFS_VERIFY_ZP(zp);
#ifdef I_DIRTY_TIME

View File

@ -63,16 +63,20 @@ zfs_fsync(znode_t *zp, int syncflag, cred_t *cr)
{
zfsvfs_t *zfsvfs = ZTOZSB(zp);
if (zfsvfs->z_os->os_sync == ZFS_SYNC_DISABLED)
return (0);
ZFS_ENTER_UNMOUNTOK(zfsvfs);
ZFS_VERIFY_ZP(zp);
(void) tsd_set(zfs_fsyncer_key, (void *)zfs_fsync_sync_cnt);
if (zfsvfs->z_os->os_sync != ZFS_SYNC_DISABLED) {
ZFS_ENTER(zfsvfs);
ZFS_VERIFY_ZP(zp);
zil_commit(zfsvfs->z_log, zp->z_id);
ZFS_EXIT(zfsvfs);
}
zil_commit(zfsvfs->z_log, zp->z_id);
tsd_set(zfs_fsyncer_key, NULL);
ZFS_EXIT(zfsvfs);
return (0);
}