Set the flag to indicate that we want new-style data writeback error handling. This means that we need to override the open routines for files and directories so that we can sample the bdev wb_err at open. Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx> --- fs/ext2/dir.c | 8 ++++++++ fs/ext2/file.c | 26 +++++++++++++++++++++----- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c index e2709695b177..6e476c9929f8 100644 --- a/fs/ext2/dir.c +++ b/fs/ext2/dir.c @@ -713,6 +713,13 @@ int ext2_empty_dir (struct inode * inode) return 0; } +static int ext2_dir_open(struct inode *inode, struct file *file) +{ + /* Sample blockdev mapping errseq_t for metadata writeback */ + file->f_md_wb_err = filemap_sample_wb_err(inode->i_sb->s_bdev->bd_inode->i_mapping); + return 0; +} + const struct file_operations ext2_dir_operations = { .llseek = generic_file_llseek, .read = generic_read_dir, @@ -721,5 +728,6 @@ const struct file_operations ext2_dir_operations = { #ifdef CONFIG_COMPAT .compat_ioctl = ext2_compat_ioctl, #endif + .open = ext2_dir_open, .fsync = ext2_fsync, }; diff --git a/fs/ext2/file.c b/fs/ext2/file.c index ed00e7ae0ef3..fd44539f6fce 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -172,17 +172,23 @@ static int ext2_release_file (struct inode * inode, struct file * filp) int ext2_fsync(struct file *file, loff_t start, loff_t end, int datasync) { - int ret; + int ret, ret2; 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) { + 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; - } + + ret2 = filemap_report_wb_err(file); + if (ret == 0) + ret = ret2; + + ret2 = filemap_report_md_wb_err(file, mapping); + if (ret == 0) + ret = ret2; return ret; } @@ -204,6 +210,16 @@ static ssize_t ext2_file_write_iter(struct kiocb *iocb, struct iov_iter *from) return generic_file_write_iter(iocb, from); } +static int ext2_file_open(struct inode *inode, struct file *file) +{ + int ret; + + ret = dquot_file_open(inode, file); + if (likely(ret == 0)) + file->f_md_wb_err = filemap_sample_wb_err(inode->i_sb->s_bdev->bd_inode->i_mapping); + return ret; +} + const struct file_operations ext2_file_operations = { .llseek = generic_file_llseek, .read_iter = ext2_file_read_iter, @@ -213,7 +229,7 @@ const struct file_operations ext2_file_operations = { .compat_ioctl = ext2_compat_ioctl, #endif .mmap = ext2_file_mmap, - .open = dquot_file_open, + .open = ext2_file_open, .release = ext2_release_file, .fsync = ext2_fsync, .get_unmapped_area = thp_get_unmapped_area, -- 2.13.0