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 <c...@kernel.org>
---
 fs/f2fs/compress.c | 61 ++++++++++++++++++++++++++--------------------
 fs/f2fs/data.c     |  4 +--
 2 files changed, 35 insertions(+), 30 deletions(-)

diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
index 9662d635efbe..1828239cef0a 100644
--- a/fs/f2fs/compress.c
+++ b/fs/f2fs/compress.c
@@ -893,14 +893,15 @@ static bool cluster_has_invalid_data(struct compress_ctx 
*cc)
 
 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);
        unsigned int cluster_size = F2FS_I(dn->inode)->i_cluster_size;
-       bool compressed = dn->data_blkaddr == COMPRESS_ADDR;
        int cluster_end = 0;
+       unsigned int count;
        int i;
        char *reason = "";
 
-       if (!compressed)
+       if (dn->data_blkaddr != COMPRESS_ADDR)
                return false;
 
        /* [..., COMPR_ADDR, ...] */
@@ -909,7 +910,7 @@ bool f2fs_sanity_check_cluster(struct dnode_of_data *dn)
                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,
                                                        dn->ofs_in_node + i);
 
@@ -929,19 +930,42 @@ bool f2fs_sanity_check_cluster(struct dnode_of_data *dn)
                        goto out;
                }
        }
+
+       f2fs_bug_on(F2FS_I_SB(dn->inode), count != cluster_size &&
+               !is_inode_flag_set(dn->inode, FI_COMPRESS_RELEASED));
+
        return false;
 out:
        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);
        set_sbi_flag(sbi, SBI_NEED_FSCK);
        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,
-                               unsigned int cluster_idx, bool compr)
+                               unsigned int cluster_idx, bool compr_blks)
 {
        struct dnode_of_data dn;
-       unsigned int cluster_size = F2FS_I(inode)->i_cluster_size;
        unsigned int start_idx = cluster_idx <<
                                F2FS_I(inode)->i_log_cluster_size;
        int ret;
@@ -956,31 +980,14 @@ static int __f2fs_cluster_blocks(struct inode *inode,
 
        if (f2fs_sanity_check_cluster(&dn)) {
                ret = -EFSCORRUPTED;
-               f2fs_handle_error(F2FS_I_SB(inode), ERROR_CORRUPTED_CLUSTER);
                goto fail;
        }
 
        if (dn.data_blkaddr == COMPRESS_ADDR) {
-               int i;
-
-               ret = 1;
-               for (i = 1; i < cluster_size; i++) {
-                       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));
+               if (compr_blks)
+                       ret = __f2fs_get_cluster_blocks(inode, &dn);
+               else
+                       ret = 1;
        }
 fail:
        f2fs_put_dnode(&dn);
@@ -993,7 +1000,7 @@ static int f2fs_compressed_blocks(struct compress_ctx *cc)
        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)
 {
        return __f2fs_cluster_blocks(inode,
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 1ac34eb49a0e..cd9cedc35d7f 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -1690,9 +1690,7 @@ int f2fs_map_blocks(struct inode *inode, struct 
f2fs_map_blocks *map, int flag)
                        map->m_flags |= F2FS_MAP_NEW;
        } else if (is_hole) {
                if (f2fs_compressed_file(inode) &&
-                   f2fs_sanity_check_cluster(&dn) &&
-                   (flag != F2FS_GET_BLOCK_FIEMAP ||
-                    IS_ENABLED(CONFIG_F2FS_CHECK_FS))) {
+                   f2fs_sanity_check_cluster(&dn)) {
                        err = -EFSCORRUPTED;
                        f2fs_handle_error(sbi,
                                        ERROR_CORRUPTED_CLUSTER);
-- 
2.40.1



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to