[RHEL7,COMMIT] ms/fs: check for writeback errors after syncing out buffers in generic_file_fsync

Submitted by Konstantin Khorenko on June 9, 2018, 10:29 a.m.

Details

Message ID 201806091029.w59ATVa7024045@finist_ce7.work
State New
Series "ms/fs: check for writeback errors after syncing out buffers in generic_file_fsync"
Headers show

Commit Message

Konstantin Khorenko June 9, 2018, 10:29 a.m.
The commit is pushed to "branch-rh7-3.10.0-862.vz7.48.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-862.el7
------>
commit 0b1d934d8bd25f057677ac353c11bb3e337d709c
Author: Vasily Averin <vvs@virtuozzo.com>
Date:   Sat Jun 9 13:29:31 2018 +0300

    ms/fs: check for writeback errors after syncing out buffers in generic_file_fsync
    
    mainline commit dac257f ("fs: check for writeback errors after syncing out buffers in generic_file_fsync")
    merged with
    mainline commit 383aa54 ("fs: convert __generic_file_fsync to use errseq_t based reporting")
    
    ext2 currently does a test+clear of the AS_EIO flag, which is
    is problematic for some coming changes.
    
    What we really need to do instead is call filemap_check_errors
    in __generic_file_fsync after syncing out the buffers. That
    will be sufficient for this case, and help other callers detect
    these errors properly as well.
    
    With that, we don't need to twiddle it in ext2.
    
    Suggested-by: Jan Kara <jack@suse.cz>
    Signed-off-by: Jeff Layton <jlayton@redhat.com>
    Reviewed-by: Christoph Hellwig <hch@lst.de>
    Reviewed-by: Jan Kara <jack@suse.cz>
    Reviewed-by: Matthew Wilcox <mawilcox@microsoft.com>
    
    fs: convert __generic_file_fsync to use errseq_t based reporting
    
    Many simple, block-based filesystems use generic_file_fsync as their
    fsync operation. Some others (ext* and fat) also call this function
    to handle syncing out data.
    
    Switch this code over to use errseq_t based error reporting so that
    all of these filesystems get reliable error reporting via fsync,
    fdatasync and msync.
    
    Signed-off-by: Jeff Layton <jlayton@redhat.com>
    Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
---
 fs/ext2/file.c | 5 +----
 fs/libfs.c     | 6 +++++-
 2 files changed, 6 insertions(+), 5 deletions(-)

Patch hide | download patch | download mbox

diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index 4d0447eb265d..9c9bc8ee0993 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -145,15 +145,12 @@  int ext2_fsync(struct file *file, loff_t start, loff_t end, int datasync)
 {
 	int ret;
 	struct super_block *sb = file->f_mapping->host->i_sb;
-	struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping;
 
 	ret = generic_file_fsync(file, start, end, datasync);
-	if (ret == -EIO || test_and_clear_bit(AS_EIO, &mapping->flags)) {
+	if (ret == -EIO)
 		/* We don't really know where the IO error happened... */
 		ext2_error(sb, __func__,
 			   "detected IO error when writing metadata buffers");
-		ret = -EIO;
-	}
 	return ret;
 }
 
diff --git a/fs/libfs.c b/fs/libfs.c
index c210f8ea358a..d1406213a539 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -956,7 +956,7 @@  int generic_file_fsync(struct file *file, loff_t start, loff_t end,
 	int err;
 	int ret;
 
-	err = filemap_write_and_wait_range(inode->i_mapping, start, end);
+	err = file_write_and_wait_range(file, start, end);
 	if (err)
 		return err;
 
@@ -972,6 +972,10 @@  int generic_file_fsync(struct file *file, loff_t start, loff_t end,
 		ret = err;
 out:
 	mutex_unlock(&inode->i_mutex);
+	/* check and advance again to catch errors after syncing out buffers */
+	err = file_check_and_advance_wb_err(file);
+	if (ret == 0)
+		ret = err;
 	return ret;
 }
 EXPORT_SYMBOL(generic_file_fsync);