fs: check for writeback errors after syncing out buffers in generic_file_fsync
authorJeff Layton <jlayton@redhat.com>
Thu, 6 Jul 2017 11:02:21 +0000 (07:02 -0400)
committerJeff Layton <jlayton@redhat.com>
Thu, 6 Jul 2017 11:02:21 +0000 (07:02 -0400)
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/ext2/file.c
fs/libfs.c

index b21891a6bfca6611f9ad89a412594c2e92d695cc..d34d32bdc944add56a4375827e044c8482665c8c 100644 (file)
@@ -174,15 +174,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;
 }
 
index a04395334bb156ae04853639650dc9751fb55753..1b76f29799bfa687df334145040e560671fc2e31 100644 (file)
@@ -991,7 +991,9 @@ int __generic_file_fsync(struct file *file, loff_t start, loff_t end,
 
 out:
        inode_unlock(inode);
-       return ret;
+       /* must call this unconditionally as it clears AS_* error flags */
+       err = filemap_check_errors(inode->i_mapping);
+       return ret ? ret : err;
 }
 EXPORT_SYMBOL(__generic_file_fsync);