diff --git a/module/os/linux/zfs/zfs_vfsops.c b/module/os/linux/zfs/zfs_vfsops.c index e6f6eb172da9..b0ccf0080110 100644 --- a/module/os/linux/zfs/zfs_vfsops.c +++ b/module/os/linux/zfs/zfs_vfsops.c @@ -1551,12 +1551,12 @@ zfs_preumount(struct super_block *sb) /* zfsvfs is NULL when zfs_domount fails during mount */ if (zfsvfs) { /* - * Since we have to disable zpl_prune_sb when umounting, - * because the shrinker gets freed before zpl_kill_sb is - * ever called, the umount might be unable to sync open files. - * - * Let's do it here. - */ + * Since we have to disable zpl_prune_sb when umounting, + * because the shrinker gets freed before zpl_kill_sb is + * ever called, the umount might be unable to sync open files. + * + * Let's do it here. + */ mutex_enter(&zfsvfs->z_znodes_lock); list_for_each_entry(zp, &zfsvfs->z_all_znodes, z_link_node) { if (zp->z_sa_hdl) diff --git a/module/os/linux/zfs/zpl_super.c b/module/os/linux/zfs/zpl_super.c index b97b701b7460..4a18537a7f15 100644 --- a/module/os/linux/zfs/zpl_super.c +++ b/module/os/linux/zfs/zpl_super.c @@ -109,11 +109,23 @@ zpl_sync_fs(struct super_block *sb, int wait) { fstrans_cookie_t cookie; cred_t *cr = CRED(); + znode_t *zp; + zfsvfs_t *zfsvfs = sb->s_fs_info; int error; crhold(cr); cookie = spl_fstrans_mark(); - error = -zfs_sync(sb, wait, cr); + mutex_enter(&zfsvfs->z_znodes_lock); + for (zp = list_head(&zfsvfs->z_all_znodes); zp; + zp = list_next(&zfsvfs->z_all_znodes, zp)) { + if (zp->z_sa_hdl) + error = -zfs_fsync(zp, wait, cr); + if (error != 0) + break; + } + mutex_exit(&zfsvfs->z_znodes_lock); + if (error == 0) + error = -zfs_sync(sb, wait, cr); spl_fstrans_unmark(cookie); crfree(cr); ASSERT3S(error, <=, 0);