f2fs: compress: fix to update i_compr_blocks correctly
authorChao Yu <chao@kernel.org>
Mon, 6 May 2024 10:41:36 +0000 (18:41 +0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Fri, 10 May 2024 03:38:27 +0000 (03:38 +0000)
Previously, we account reserved blocks and compressed blocks into
@compr_blocks, then, f2fs_i_compr_blocks_update(,compr_blocks) will
update i_compr_blocks incorrectly, fix it.

Meanwhile, for the case all blocks in cluster were reserved, fix to
update dn->ofs_in_node correctly.

Fixes: eb8fbaa53374 ("f2fs: compress: fix to check unreleased compressed cluster")
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/file.c

index 72ce1a522fb26a8a2e0e793534a8cf291f1505f4..13b430b54299d321498d3c2f984f00f78b7ef169 100644 (file)
@@ -3666,7 +3666,8 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count,
 
        while (count) {
                int compr_blocks = 0;
-               blkcnt_t reserved;
+               blkcnt_t reserved = 0;
+               blkcnt_t to_reserved;
                int ret;
 
                for (i = 0; i < cluster_size; i++) {
@@ -3686,20 +3687,26 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count,
                         * fails in release_compress_blocks(), so NEW_ADDR
                         * is a possible case.
                         */
-                       if (blkaddr == NEW_ADDR ||
-                               __is_valid_data_blkaddr(blkaddr)) {
+                       if (blkaddr == NEW_ADDR) {
+                               reserved++;
+                               continue;
+                       }
+                       if (__is_valid_data_blkaddr(blkaddr)) {
                                compr_blocks++;
                                continue;
                        }
                }
 
-               reserved = cluster_size - compr_blocks;
+               to_reserved = cluster_size - compr_blocks - reserved;
 
                /* for the case all blocks in cluster were reserved */
-               if (reserved == 1)
+               if (to_reserved == 1) {
+                       dn->ofs_in_node += cluster_size;
                        goto next;
+               }
 
-               ret = inc_valid_block_count(sbi, dn->inode, &reserved, false);
+               ret = inc_valid_block_count(sbi, dn->inode,
+                                               &to_reserved, false);
                if (unlikely(ret))
                        return ret;
 
@@ -3710,7 +3717,7 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count,
 
                f2fs_i_compr_blocks_update(dn->inode, compr_blocks, true);
 
-               *reserved_blocks += reserved;
+               *reserved_blocks += to_reserved;
 next:
                count -= cluster_size;
        }