f2fs: fix to do sanity check on extent cache correctly
In do_read_inode(), sanity check for extent cache should be called after
f2fs_init_read_extent_tree(), fix it.
Fixes: 72840cccc0
("f2fs: allocate the extent_cache by default")
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
parent
9e615dbba4
commit
269d119481
|
@ -19,6 +19,31 @@
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include <trace/events/f2fs.h>
|
#include <trace/events/f2fs.h>
|
||||||
|
|
||||||
|
bool sanity_check_extent_cache(struct inode *inode)
|
||||||
|
{
|
||||||
|
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
|
||||||
|
struct f2fs_inode_info *fi = F2FS_I(inode);
|
||||||
|
struct extent_info *ei;
|
||||||
|
|
||||||
|
if (!fi->extent_tree[EX_READ])
|
||||||
|
return true;
|
||||||
|
|
||||||
|
ei = &fi->extent_tree[EX_READ]->largest;
|
||||||
|
|
||||||
|
if (ei->len &&
|
||||||
|
(!f2fs_is_valid_blkaddr(sbi, ei->blk,
|
||||||
|
DATA_GENERIC_ENHANCE) ||
|
||||||
|
!f2fs_is_valid_blkaddr(sbi, ei->blk + ei->len - 1,
|
||||||
|
DATA_GENERIC_ENHANCE))) {
|
||||||
|
set_sbi_flag(sbi, SBI_NEED_FSCK);
|
||||||
|
f2fs_warn(sbi, "%s: inode (ino=%lx) extent info [%u, %u, %u] is incorrect, run fsck to fix",
|
||||||
|
__func__, inode->i_ino,
|
||||||
|
ei->blk, ei->fofs, ei->len);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static void __set_extent_info(struct extent_info *ei,
|
static void __set_extent_info(struct extent_info *ei,
|
||||||
unsigned int fofs, unsigned int len,
|
unsigned int fofs, unsigned int len,
|
||||||
block_t blk, bool keep_clen,
|
block_t blk, bool keep_clen,
|
||||||
|
|
|
@ -4137,6 +4137,7 @@ void f2fs_leave_shrinker(struct f2fs_sb_info *sbi);
|
||||||
/*
|
/*
|
||||||
* extent_cache.c
|
* extent_cache.c
|
||||||
*/
|
*/
|
||||||
|
bool sanity_check_extent_cache(struct inode *inode);
|
||||||
struct rb_entry *f2fs_lookup_rb_tree(struct rb_root_cached *root,
|
struct rb_entry *f2fs_lookup_rb_tree(struct rb_root_cached *root,
|
||||||
struct rb_entry *cached_re, unsigned int ofs);
|
struct rb_entry *cached_re, unsigned int ofs);
|
||||||
struct rb_node **f2fs_lookup_rb_tree_ext(struct f2fs_sb_info *sbi,
|
struct rb_node **f2fs_lookup_rb_tree_ext(struct f2fs_sb_info *sbi,
|
||||||
|
|
|
@ -262,22 +262,6 @@ static bool sanity_check_inode(struct inode *inode, struct page *node_page)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fi->extent_tree[EX_READ]) {
|
|
||||||
struct extent_info *ei = &fi->extent_tree[EX_READ]->largest;
|
|
||||||
|
|
||||||
if (ei->len &&
|
|
||||||
(!f2fs_is_valid_blkaddr(sbi, ei->blk,
|
|
||||||
DATA_GENERIC_ENHANCE) ||
|
|
||||||
!f2fs_is_valid_blkaddr(sbi, ei->blk + ei->len - 1,
|
|
||||||
DATA_GENERIC_ENHANCE))) {
|
|
||||||
set_sbi_flag(sbi, SBI_NEED_FSCK);
|
|
||||||
f2fs_warn(sbi, "%s: inode (ino=%lx) extent info [%u, %u, %u] is incorrect, run fsck to fix",
|
|
||||||
__func__, inode->i_ino,
|
|
||||||
ei->blk, ei->fofs, ei->len);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (f2fs_sanity_check_inline_data(inode)) {
|
if (f2fs_sanity_check_inline_data(inode)) {
|
||||||
set_sbi_flag(sbi, SBI_NEED_FSCK);
|
set_sbi_flag(sbi, SBI_NEED_FSCK);
|
||||||
f2fs_warn(sbi, "%s: inode (ino=%lx, mode=%u) should not have inline_data, run fsck to fix",
|
f2fs_warn(sbi, "%s: inode (ino=%lx, mode=%u) should not have inline_data, run fsck to fix",
|
||||||
|
@ -488,6 +472,12 @@ static int do_read_inode(struct inode *inode)
|
||||||
return -EFSCORRUPTED;
|
return -EFSCORRUPTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!sanity_check_extent_cache(inode)) {
|
||||||
|
f2fs_put_page(node_page, 1);
|
||||||
|
f2fs_handle_error(sbi, ERROR_CORRUPTED_INODE);
|
||||||
|
return -EFSCORRUPTED;
|
||||||
|
}
|
||||||
|
|
||||||
f2fs_put_page(node_page, 1);
|
f2fs_put_page(node_page, 1);
|
||||||
|
|
||||||
stat_inc_inline_xattr(inode);
|
stat_inc_inline_xattr(inode);
|
||||||
|
|
Loading…
Reference in New Issue