Skip to content

Commit

Permalink
Linux: syncfs(2) should sync cached dirty data
Browse files Browse the repository at this point in the history
While debugging problem with data not being synced on umount, we've
noticed that even syncfs(2) doesn't help to get the data written
out. It is because it doesn't actually sync any of the live znodes.

Signed-off-by: Pavel Snajdr <snajpa@snajpa.net>
  • Loading branch information
snajpa committed Nov 30, 2024
1 parent 849a236 commit 02cf3bf
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 2 deletions.
2 changes: 2 additions & 0 deletions include/os/linux/zfs/sys/zpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion module/os/linux/zfs/zpl_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
20 changes: 19 additions & 1 deletion module/os/linux/zfs/zpl_super.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,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);
Expand Down

0 comments on commit 02cf3bf

Please sign in to comment.