summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2019-05-22 10:27:01 -0400
committerBen Hutchings <ben@decadent.org.uk>2020-06-11 19:05:55 +0100
commit71bfaf9e30125ec5b408fd328e412abf3b23214d (patch)
tree7284ad5c8914b6f9bee6de0d6e45151fb66052c3
parenta8a1d01018f66c5cc3cb2a4c194e55edcf0e50ec (diff)
downloadlinux-stable-71bfaf9e30125ec5b408fd328e412abf3b23214d.tar.gz
linux-stable-71bfaf9e30125ec5b408fd328e412abf3b23214d.tar.bz2
linux-stable-71bfaf9e30125ec5b408fd328e412abf3b23214d.zip
ext4: don't perform block validity checks on the journal inode
commit 0a944e8a6c66ca04c7afbaa17e22bf208a8b37f0 upstream. Since the journal inode is already checked when we added it to the block validity's system zone, if we check it again, we'll just trigger a failure. This was causing failures like this: [ 53.897001] EXT4-fs error (device sda): ext4_find_extent:909: inode #8: comm jbd2/sda-8: pblk 121667583 bad header/extent: invalid extent entries - magic f30a, entries 8, max 340(340), depth 0(0) [ 53.931430] jbd2_journal_bmap: journal block not found at offset 49 on sda-8 [ 53.938480] Aborting journal on device sda-8. ... but only if the system was under enough memory pressure that logical->physical mapping for the journal inode gets pushed out of the extent cache. (This is why it wasn't noticed earlier.) Fixes: 345c0dbf3a30 ("ext4: protect journal inode's blocks using block_validity") Reported-by: Dan Rue <dan.rue@linaro.org> Signed-off-by: Theodore Ts'o <tytso@mit.edu> Tested-by: Naresh Kamboju <naresh.kamboju@linaro.org> [bwh: Backported to 3.16: Use EXT4_HAS_COMPAT_FEATURE()] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r--fs/ext4/extents.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 02dca6c43316..43602f4b0ae5 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -503,10 +503,15 @@ __read_extent_tree_block(const char *function, unsigned int line,
}
if (buffer_verified(bh) && !(flags & EXT4_EX_FORCE_CACHE))
return bh;
- err = __ext4_ext_check(function, line, inode,
- ext_block_hdr(bh), depth, pblk);
- if (err)
- goto errout;
+ if (!EXT4_HAS_COMPAT_FEATURE(inode->i_sb,
+ EXT4_FEATURE_COMPAT_HAS_JOURNAL) ||
+ (inode->i_ino !=
+ le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_journal_inum))) {
+ err = __ext4_ext_check(function, line, inode,
+ ext_block_hdr(bh), depth, pblk);
+ if (err)
+ goto errout;
+ }
set_buffer_verified(bh);
/*
* If this is a leaf block, cache all of its entries