diff --git a/include/os/linux/zfs/sys/zpl.h b/include/os/linux/zfs/sys/zpl.h index c6e235c48ef3..dd35c343036f 100644 --- a/include/os/linux/zfs/sys/zpl.h +++ b/include/os/linux/zfs/sys/zpl.h @@ -49,6 +49,8 @@ extern const struct inode_operations zpl_special_inode_operations; extern const struct address_space_operations zpl_address_space_operations; extern const struct file_operations zpl_file_operations; extern const struct file_operations zpl_dir_file_operations; +extern int zpl_writepages(struct address_space *mapping, + struct writeback_control *wbc); /* zpl_super.c */ extern void zpl_prune_sb(uint64_t nr_to_scan, void *arg); diff --git a/module/os/linux/zfs/zpl_file.c b/module/os/linux/zfs/zpl_file.c index f6e014327717..1ebdd83b1d68 100644 --- a/module/os/linux/zfs/zpl_file.c +++ b/module/os/linux/zfs/zpl_file.c @@ -546,7 +546,7 @@ zpl_write_cache_pages(struct address_space *mapping, return (result); } -static int +int zpl_writepages(struct address_space *mapping, struct writeback_control *wbc) { znode_t *zp = ITOZ(mapping->host); diff --git a/module/os/linux/zfs/zpl_super.c b/module/os/linux/zfs/zpl_super.c index b97b701b7460..c952c89c718f 100644 --- a/module/os/linux/zfs/zpl_super.c +++ b/module/os/linux/zfs/zpl_super.c @@ -109,11 +109,29 @@ 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; + struct writeback_control wbc = { + .sync_mode = wait ? WB_SYNC_ALL : WB_SYNC_NONE, + .nr_to_write = LONG_MAX, + .range_start = 0, + .range_end = LLONG_MAX, + }; 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 = zpl_writepages(ZTOI(zp)->i_mapping, &wbc); + 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);