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 <c...@kernel.org>
---
 fs/f2fs/file.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 1761ad125f97..6c84485687d3 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -3641,7 +3641,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++) {
@@ -3661,20 +3662,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;
 
@@ -3685,7 +3692,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;
        }
-- 
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