mirror of
https://github.com/nxp-imx/linux-imx.git
synced 2025-07-07 18:05:21 +02:00
f2fs: compress: do sanity check on cluster when CONFIG_F2FS_CHECK_FS is on
[ Upstream commit2aaea533bf
] This patch covers sanity check logic on cluster w/ CONFIG_F2FS_CHECK_FS, otherwise, there will be performance regression while querying cluster mapping info. Callers of f2fs_is_compressed_cluster() only care about whether cluster is compressed or not, rather than # of valid blocks in compressed cluster, so, let's adjust f2fs_is_compressed_cluster()'s logic according to caller's requirement. Signed-off-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> Stable-dep-of:f785cec298
("f2fs: compress: don't redirty sparse cluster during {,de}compress") Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
fc18e655b6
commit
4263b3ef81
|
@ -887,14 +887,15 @@ static bool cluster_has_invalid_data(struct compress_ctx *cc)
|
||||||
|
|
||||||
bool f2fs_sanity_check_cluster(struct dnode_of_data *dn)
|
bool f2fs_sanity_check_cluster(struct dnode_of_data *dn)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_F2FS_CHECK_FS
|
||||||
struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
|
struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
|
||||||
unsigned int cluster_size = F2FS_I(dn->inode)->i_cluster_size;
|
unsigned int cluster_size = F2FS_I(dn->inode)->i_cluster_size;
|
||||||
bool compressed = dn->data_blkaddr == COMPRESS_ADDR;
|
|
||||||
int cluster_end = 0;
|
int cluster_end = 0;
|
||||||
|
unsigned int count;
|
||||||
int i;
|
int i;
|
||||||
char *reason = "";
|
char *reason = "";
|
||||||
|
|
||||||
if (!compressed)
|
if (dn->data_blkaddr != COMPRESS_ADDR)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* [..., COMPR_ADDR, ...] */
|
/* [..., COMPR_ADDR, ...] */
|
||||||
|
@ -903,7 +904,7 @@ bool f2fs_sanity_check_cluster(struct dnode_of_data *dn)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 1; i < cluster_size; i++) {
|
for (i = 1, count = 1; i < cluster_size; i++, count++) {
|
||||||
block_t blkaddr = data_blkaddr(dn->inode, dn->node_page,
|
block_t blkaddr = data_blkaddr(dn->inode, dn->node_page,
|
||||||
dn->ofs_in_node + i);
|
dn->ofs_in_node + i);
|
||||||
|
|
||||||
|
@ -923,19 +924,42 @@ bool f2fs_sanity_check_cluster(struct dnode_of_data *dn)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f2fs_bug_on(F2FS_I_SB(dn->inode), count != cluster_size &&
|
||||||
|
!is_inode_flag_set(dn->inode, FI_COMPRESS_RELEASED));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
out:
|
out:
|
||||||
f2fs_warn(sbi, "access invalid cluster, ino:%lu, nid:%u, ofs_in_node:%u, reason:%s",
|
f2fs_warn(sbi, "access invalid cluster, ino:%lu, nid:%u, ofs_in_node:%u, reason:%s",
|
||||||
dn->inode->i_ino, dn->nid, dn->ofs_in_node, reason);
|
dn->inode->i_ino, dn->nid, dn->ofs_in_node, reason);
|
||||||
set_sbi_flag(sbi, SBI_NEED_FSCK);
|
set_sbi_flag(sbi, SBI_NEED_FSCK);
|
||||||
return true;
|
return true;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __f2fs_get_cluster_blocks(struct inode *inode,
|
||||||
|
struct dnode_of_data *dn)
|
||||||
|
{
|
||||||
|
unsigned int cluster_size = F2FS_I(inode)->i_cluster_size;
|
||||||
|
int count, i;
|
||||||
|
|
||||||
|
for (i = 1, count = 1; i < cluster_size; i++) {
|
||||||
|
block_t blkaddr = data_blkaddr(dn->inode, dn->node_page,
|
||||||
|
dn->ofs_in_node + i);
|
||||||
|
|
||||||
|
if (__is_valid_data_blkaddr(blkaddr))
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __f2fs_cluster_blocks(struct inode *inode,
|
static int __f2fs_cluster_blocks(struct inode *inode,
|
||||||
unsigned int cluster_idx, bool compr)
|
unsigned int cluster_idx, bool compr_blks)
|
||||||
{
|
{
|
||||||
struct dnode_of_data dn;
|
struct dnode_of_data dn;
|
||||||
unsigned int cluster_size = F2FS_I(inode)->i_cluster_size;
|
|
||||||
unsigned int start_idx = cluster_idx <<
|
unsigned int start_idx = cluster_idx <<
|
||||||
F2FS_I(inode)->i_log_cluster_size;
|
F2FS_I(inode)->i_log_cluster_size;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -950,31 +974,14 @@ static int __f2fs_cluster_blocks(struct inode *inode,
|
||||||
|
|
||||||
if (f2fs_sanity_check_cluster(&dn)) {
|
if (f2fs_sanity_check_cluster(&dn)) {
|
||||||
ret = -EFSCORRUPTED;
|
ret = -EFSCORRUPTED;
|
||||||
f2fs_handle_error(F2FS_I_SB(inode), ERROR_CORRUPTED_CLUSTER);
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dn.data_blkaddr == COMPRESS_ADDR) {
|
if (dn.data_blkaddr == COMPRESS_ADDR) {
|
||||||
int i;
|
if (compr_blks)
|
||||||
|
ret = __f2fs_get_cluster_blocks(inode, &dn);
|
||||||
ret = 1;
|
else
|
||||||
for (i = 1; i < cluster_size; i++) {
|
ret = 1;
|
||||||
block_t blkaddr;
|
|
||||||
|
|
||||||
blkaddr = data_blkaddr(dn.inode,
|
|
||||||
dn.node_page, dn.ofs_in_node + i);
|
|
||||||
if (compr) {
|
|
||||||
if (__is_valid_data_blkaddr(blkaddr))
|
|
||||||
ret++;
|
|
||||||
} else {
|
|
||||||
if (blkaddr != NULL_ADDR)
|
|
||||||
ret++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
f2fs_bug_on(F2FS_I_SB(inode),
|
|
||||||
!compr && ret != cluster_size &&
|
|
||||||
!is_inode_flag_set(inode, FI_COMPRESS_RELEASED));
|
|
||||||
}
|
}
|
||||||
fail:
|
fail:
|
||||||
f2fs_put_dnode(&dn);
|
f2fs_put_dnode(&dn);
|
||||||
|
@ -987,7 +994,7 @@ static int f2fs_compressed_blocks(struct compress_ctx *cc)
|
||||||
return __f2fs_cluster_blocks(cc->inode, cc->cluster_idx, true);
|
return __f2fs_cluster_blocks(cc->inode, cc->cluster_idx, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return # of valid blocks in compressed cluster */
|
/* return whether cluster is compressed one or not */
|
||||||
int f2fs_is_compressed_cluster(struct inode *inode, pgoff_t index)
|
int f2fs_is_compressed_cluster(struct inode *inode, pgoff_t index)
|
||||||
{
|
{
|
||||||
return __f2fs_cluster_blocks(inode,
|
return __f2fs_cluster_blocks(inode,
|
||||||
|
|
|
@ -1614,9 +1614,7 @@ next_block:
|
||||||
map->m_flags |= F2FS_MAP_NEW;
|
map->m_flags |= F2FS_MAP_NEW;
|
||||||
} else if (is_hole) {
|
} else if (is_hole) {
|
||||||
if (f2fs_compressed_file(inode) &&
|
if (f2fs_compressed_file(inode) &&
|
||||||
f2fs_sanity_check_cluster(&dn) &&
|
f2fs_sanity_check_cluster(&dn)) {
|
||||||
(flag != F2FS_GET_BLOCK_FIEMAP ||
|
|
||||||
IS_ENABLED(CONFIG_F2FS_CHECK_FS))) {
|
|
||||||
err = -EFSCORRUPTED;
|
err = -EFSCORRUPTED;
|
||||||
f2fs_handle_error(sbi,
|
f2fs_handle_error(sbi,
|
||||||
ERROR_CORRUPTED_CLUSTER);
|
ERROR_CORRUPTED_CLUSTER);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user