Provide an implementation for ->syncfs(). Now if there is an error returned by sync_filesystem(upper_sb), it will be visible to user space. Currently in ovl_sync_fs() path, this error is ignored by VFS. A later patch also adds logic to detect writeback error. Signed-off-by: Vivek Goyal <vgoyal@xxxxxxxxxx> --- fs/overlayfs/file.c | 1 + fs/overlayfs/overlayfs.h | 3 +++ fs/overlayfs/readdir.c | 1 + fs/overlayfs/super.c | 30 ++++++++++++++++++++++++++++++ 4 files changed, 35 insertions(+) diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c index efccb7c1f9bc..affc1ba63202 100644 --- a/fs/overlayfs/file.c +++ b/fs/overlayfs/file.c @@ -806,6 +806,7 @@ const struct file_operations ovl_file_operations = { .copy_file_range = ovl_copy_file_range, .remap_file_range = ovl_remap_file_range, + .syncfs = ovl_syncfs, }; int __init ovl_aio_request_cache_init(void) diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index f8880aa2ba0e..1efb13800755 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -520,3 +520,6 @@ int ovl_set_origin(struct dentry *dentry, struct dentry *lower, /* export.c */ extern const struct export_operations ovl_export_operations; + +/* super.c */ +int ovl_syncfs(struct file *file); diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c index 01620ebae1bd..e89b450c8f8f 100644 --- a/fs/overlayfs/readdir.c +++ b/fs/overlayfs/readdir.c @@ -975,6 +975,7 @@ const struct file_operations ovl_dir_operations = { #ifdef CONFIG_COMPAT .compat_ioctl = ovl_compat_ioctl, #endif + .syncfs = ovl_syncfs, }; int ovl_check_empty_dir(struct dentry *dentry, struct list_head *list) diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index 290983bcfbb3..b4d92e6fa5ce 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -286,6 +286,36 @@ static int ovl_sync_fs(struct super_block *sb, int wait) return ret; } +int ovl_syncfs(struct file *file) +{ + struct super_block *sb = file->f_path.dentry->d_sb; + struct ovl_fs *ofs = sb->s_fs_info; + struct super_block *upper_sb; + int ret; + + ret = 0; + down_read(&sb->s_umount); + if (sb_rdonly(sb)) + goto out; + + if (!ovl_upper_mnt(ofs)) + goto out; + + if (!ovl_should_sync(ofs)) + goto out; + + upper_sb = ovl_upper_mnt(ofs)->mnt_sb; + + down_read(&upper_sb->s_umount); + ret = sync_filesystem(upper_sb); + up_read(&upper_sb->s_umount); + + +out: + up_read(&sb->s_umount); + return ret; +} + /** * ovl_statfs * @sb: The overlayfs super block -- 2.25.4