summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2017-07-06 07:02:21 -0400
committerJeff Layton <jlayton@redhat.com>2017-07-06 07:02:21 -0400
commitdac257f7419c732be3e491bbbb568a82df60208a (patch)
tree716ff1d0955826e258d73213aeb3053eb3c2fe53
parentd945b59db8449ab8323995391c6a63525b3666f6 (diff)
downloadlwn-dac257f7419c732be3e491bbbb568a82df60208a.tar.gz
lwn-dac257f7419c732be3e491bbbb568a82df60208a.zip
fs: check for writeback errors after syncing out buffers in generic_file_fsync
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>
-rw-r--r--fs/ext2/file.c5
-rw-r--r--fs/libfs.c4
2 files changed, 4 insertions, 5 deletions
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index b21891a6bfca..d34d32bdc944 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -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;
}
diff --git a/fs/libfs.c b/fs/libfs.c
index a04395334bb1..1b76f29799bf 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -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);