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

Konstantin Khorenko khorenko at virtuozzo.com
Sat Jun 9 13:29:31 MSK 2018


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 at 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 at suse.cz>
    Signed-off-by: Jeff Layton <jlayton at redhat.com>
    Reviewed-by: Christoph Hellwig <hch at lst.de>
    Reviewed-by: Jan Kara <jack at suse.cz>
    Reviewed-by: Matthew Wilcox <mawilcox at 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 at redhat.com>
    Signed-off-by: Vasily Averin <vvs at virtuozzo.com>
---
 fs/ext2/file.c | 5 +----
 fs/libfs.c     | 6 +++++-
 2 files changed, 6 insertions(+), 5 deletions(-)

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);


More information about the Devel mailing list