[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20170612122316.13244-11-jlayton@redhat.com>
Date: Mon, 12 Jun 2017 08:23:02 -0400
From: Jeff Layton <jlayton@...hat.com>
To: Andrew Morton <akpm@...ux-foundation.org>,
Al Viro <viro@...IV.linux.org.uk>, Jan Kara <jack@...e.cz>,
tytso@....edu, axboe@...nel.dk, mawilcox@...rosoft.com,
ross.zwisler@...ux.intel.com, corbet@....net,
Chris Mason <clm@...com>, Josef Bacik <jbacik@...com>,
David Sterba <dsterba@...e.com>,
"Darrick J . Wong" <darrick.wong@...cle.com>
Cc: linux-fsdevel@...r.kernel.org, linux-mm@...ck.org,
linux-ext4@...r.kernel.org, linux-xfs@...r.kernel.org,
linux-btrfs@...r.kernel.org, linux-block@...r.kernel.org
Subject: [PATCH v6 10/13] ext4: add more robust reporting of metadata writeback errors
ext4 uses the blockdev mapping for tracking metadata stored in the
pagecache. Sample its wb_err when opening a file and store that in
the f_md_wb_err field.
Change ext4_sync_file to check for data errors first, and then check the
blockdev mapping for metadata errors afterward.
Note that because metadata writeback errors are only tracked on a
per-device level, this does mean that we'll end up reporting an error on
all open file descriptors when there is a metadata writeback failure.
That's not ideal, but we can possibly improve upon it in the future.
Signed-off-by: Jeff Layton <jlayton@...hat.com>
---
fs/ext4/dir.c | 8 ++++++--
fs/ext4/file.c | 5 ++++-
fs/ext4/fsync.c | 13 +++++++++++++
3 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index e8b365000d73..6bbb19510f74 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -611,9 +611,13 @@ static int ext4_dx_readdir(struct file *file, struct dir_context *ctx)
static int ext4_dir_open(struct inode * inode, struct file * filp)
{
+ int ret = 0;
+
if (ext4_encrypted_inode(inode))
- return fscrypt_get_encryption_info(inode) ? -EACCES : 0;
- return 0;
+ ret = fscrypt_get_encryption_info(inode) ? -EACCES : 0;
+ if (!ret)
+ filp->f_md_wb_err = filemap_sample_wb_err(inode->i_sb->s_bdev->bd_inode->i_mapping);
+ return ret;
}
static int ext4_release_dir(struct inode *inode, struct file *filp)
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 831fd6beebf0..fe0d6e01c4b7 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -435,7 +435,10 @@ static int ext4_file_open(struct inode * inode, struct file * filp)
if (ret < 0)
return ret;
}
- return dquot_file_open(inode, filp);
+ ret = dquot_file_open(inode, filp);
+ if (!ret)
+ filp->f_md_wb_err = filemap_sample_wb_err(sb->s_bdev->bd_inode->i_mapping);
+ return ret;
}
/*
diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c
index 03d6259d8662..36363a6730d7 100644
--- a/fs/ext4/fsync.c
+++ b/fs/ext4/fsync.c
@@ -165,6 +165,19 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
err = filemap_report_wb_err(file);
if (!ret)
ret = err;
+
+ /*
+ * Was there a metadata writeback error since last fsync?
+ *
+ * FIXME: ext4 tracks metadata with a whole-block device mapping. So,
+ * if there is any sort of metadata writeback error, we'll report an
+ * error on all open fds, even ones not associated with the inode
+ */
+ err = filemap_report_md_wb_err(file,
+ inode->i_sb->s_bdev->bd_inode->i_mapping);
+ if (!ret)
+ ret = err;
+
trace_ext4_sync_file_exit(inode, ret);
return ret;
}
--
2.13.0
Powered by blists - more mailing lists