From: Chao Yu <[email protected]>

[ Upstream commit 1a67cbe141cf991af252a88143d0fd975be2d9e7 ]

por_fsstress reports inconsistent status in orphan inode, the root cause
of this is in f2fs_write_raw_pages() we decrease i_compr_blocks incorrectly
due to wrong calculation in f2fs_compressed_blocks().

So this patch exposes below two functions based on __f2fs_cluster_blocks:
- f2fs_compressed_blocks: get count of compressed blocks in compressed cluster
- f2fs_cluster_blocks: get count of valid blocks (including reserved blocks)
in compressed cluster.

Then use f2fs_compress_blocks() to get correct compressed blocks count in
f2fs_write_raw_pages().

sanity_check_inode: inode (ino=ad80) hash inconsistent i_compr_blocks:2, 
i_blocks:1, run fsck to fix

Signed-off-by: Chao Yu <[email protected]>
Signed-off-by: Jaegeuk Kim <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
 fs/f2fs/compress.c | 28 ++++++++++++++++++++++------
 1 file changed, 22 insertions(+), 6 deletions(-)

diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
index ad8e25a1fbc26..11b13b881ada5 100644
--- a/fs/f2fs/compress.c
+++ b/fs/f2fs/compress.c
@@ -536,8 +536,7 @@ static bool __cluster_may_compress(struct compress_ctx *cc)
        return true;
 }
 
-/* return # of compressed block addresses */
-static int f2fs_compressed_blocks(struct compress_ctx *cc)
+static int __f2fs_cluster_blocks(struct compress_ctx *cc, bool compr)
 {
        struct dnode_of_data dn;
        int ret;
@@ -560,8 +559,13 @@ static int f2fs_compressed_blocks(struct compress_ctx *cc)
 
                        blkaddr = datablock_addr(dn.inode,
                                        dn.node_page, dn.ofs_in_node + i);
-                       if (blkaddr != NULL_ADDR)
-                               ret++;
+                       if (compr) {
+                               if (__is_valid_data_blkaddr(blkaddr))
+                                       ret++;
+                       } else {
+                               if (blkaddr != NULL_ADDR)
+                                       ret++;
+                       }
                }
        }
 fail:
@@ -569,6 +573,18 @@ static int f2fs_compressed_blocks(struct compress_ctx *cc)
        return ret;
 }
 
+/* return # of compressed blocks in compressed cluster */
+static int f2fs_compressed_blocks(struct compress_ctx *cc)
+{
+       return __f2fs_cluster_blocks(cc, true);
+}
+
+/* return # of valid blocks in compressed cluster */
+static int f2fs_cluster_blocks(struct compress_ctx *cc, bool compr)
+{
+       return __f2fs_cluster_blocks(cc, false);
+}
+
 int f2fs_is_compressed_cluster(struct inode *inode, pgoff_t index)
 {
        struct compress_ctx cc = {
@@ -578,7 +594,7 @@ int f2fs_is_compressed_cluster(struct inode *inode, pgoff_t 
index)
                .cluster_idx = index >> F2FS_I(inode)->i_log_cluster_size,
        };
 
-       return f2fs_compressed_blocks(&cc);
+       return f2fs_cluster_blocks(&cc, false);
 }
 
 static bool cluster_may_compress(struct compress_ctx *cc)
@@ -627,7 +643,7 @@ static int prepare_compress_overwrite(struct compress_ctx 
*cc,
        bool prealloc;
 
 retry:
-       ret = f2fs_compressed_blocks(cc);
+       ret = f2fs_cluster_blocks(cc, false);
        if (ret <= 0)
                return ret;
 
-- 
2.20.1



_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to