[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20200526071754.33819-9-yi.zhang@huawei.com>
Date: Tue, 26 May 2020 15:17:52 +0800
From: "zhangyi (F)" <yi.zhang@...wei.com>
To: <linux-ext4@...r.kernel.org>
CC: <tytso@....edu>, <jack@...e.cz>, <adilger.kernel@...ger.ca>,
<yi.zhang@...wei.com>, <zhangxiaoxu5@...wei.com>
Subject: [PATCH 08/10] ext4: replace sb_breadahead() with ext4_sb_breadahead()
For the cases of read ahead blocks, we also need to check the write io
error flag to prevent reading block from disk if it is actually
uptodate. Add a new wrapper ext4_sb_breadahead() to check the uptodate
flag and prevent unnecessary read operation, and replace all
sb_breadahead().
Signed-off-by: zhangyi (F) <yi.zhang@...wei.com>
---
fs/ext4/ext4.h | 11 +++++------
fs/ext4/inode.c | 2 +-
fs/ext4/super.c | 19 ++++++++++++++++++-
3 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 81c1bdfb9397..cafa2617a093 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -2767,6 +2767,8 @@ extern struct buffer_head *__ext4_sb_getblk(struct super_block *sb,
extern struct buffer_head *__ext4_sb_bread_gfp(struct super_block *sb,
sector_t block, int op_flags,
gfp_t gfp);
+extern void ext4_sb_breadahead_unmovable(struct super_block *sb,
+ sector_t block);
extern int ext4_seq_options_show(struct seq_file *seq, void *offset);
extern int ext4_calculate_overhead(struct super_block *sb);
extern void ext4_superblock_csum_set(struct super_block *sb);
@@ -3533,13 +3535,10 @@ static inline int ext4_buffer_uptodate(struct buffer_head *bh)
{
/*
* If the buffer has the write error flag, we have failed
- * to write out data in the block. In this case, we don't
- * have to read the block because we may read the old data
- * successfully.
+ * to write out this metadata block. In this case, the data
+ * in this block is uptodate.
*/
- if (!buffer_uptodate(bh) && buffer_write_io_error(bh))
- set_buffer_uptodate(bh);
- return buffer_uptodate(bh);
+ return buffer_uptodate(bh) || buffer_write_io_error(bh);
}
#endif /* __KERNEL__ */
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 4989a9633fc7..7354edb444c5 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4351,7 +4351,7 @@ static int __ext4_get_inode_loc(struct inode *inode,
if (end > table)
end = table;
while (b <= end)
- sb_breadahead_unmovable(sb, b++);
+ ext4_sb_breadahead_unmovable(sb, b++);
}
/*
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index b9aab334a5d0..d25a0fe44bec 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -218,6 +218,23 @@ __ext4_sb_bread_gfp(struct super_block *sb, sector_t block,
return ERR_PTR(-EIO);
}
+/*
+ * This works like sb_breadahead_unmovable() except it use
+ * ext4_buffer_uptodate() instead of buffer_uptodate() to check the
+ * metadata buffer is actually uptodate or not. The buffer should be
+ * considered as actually uptodate for the case of it has been
+ * failed to write out.
+ */
+void ext4_sb_breadahead_unmovable(struct super_block *sb, sector_t block)
+{
+ struct buffer_head *bh = ext4_sb_getblk_gfp(sb, block, 0);
+
+ if (likely(bh) && !ext4_buffer_uptodate(bh)) {
+ ll_rw_block(REQ_OP_READ, REQ_META | REQ_RAHEAD, 1, &bh);
+ brelse(bh);
+ }
+}
+
static int ext4_verify_csum_type(struct super_block *sb,
struct ext4_super_block *es)
{
@@ -4395,7 +4412,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
/* Pre-read the descriptors into the buffer cache */
for (i = 0; i < db_count; i++) {
block = descriptor_loc(sb, logical_sb_block, i);
- sb_breadahead_unmovable(sb, block);
+ ext4_sb_breadahead_unmovable(sb, block);
}
for (i = 0; i < db_count; i++) {
--
2.21.3
Powered by blists - more mailing lists