From d526904e82411b27f878e245b74a0411e3a8ea32 Mon Sep 17 00:00:00 2001 From: ngkaho1234 Date: Sun, 27 Sep 2015 13:09:11 +0800 Subject: [PATCH] FIX: an extra block is freed when truncating an inode. --- lwext4/ext4_fs.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/lwext4/ext4_fs.c b/lwext4/ext4_fs.c index 0668b55..dccde5e 100644 --- a/lwext4/ext4_fs.c +++ b/lwext4/ext4_fs.c @@ -908,25 +908,26 @@ int ext4_fs_truncate_inode(struct ext4_inode_ref *inode_ref, uint64_t new_size) } /* Compute how many blocks will be released */ - uint64_t size_diff = old_size - new_size; uint32_t block_size = ext4_sb_get_block_size(sb); - uint32_t diff_blocks_count = size_diff / block_size; - if (size_diff % block_size != 0) - diff_blocks_count++; - - uint32_t old_blocks_count = old_size / block_size; - if (old_size % block_size != 0) - old_blocks_count++; + uint32_t new_blocks_count = (new_size + block_size - 1) / + block_size; + uint32_t old_blocks_count = (old_size + block_size - 1) / + block_size; + uint32_t diff_blocks_count = old_blocks_count - new_blocks_count; #if CONFIG_EXTENT_ENABLE if ((ext4_sb_has_feature_incompatible(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) && (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) { /* Extents require special operation */ - int rc = ext4_extent_release_blocks_from( - inode_ref, old_blocks_count - diff_blocks_count); - if (rc != EOK) - return rc; + if (diff_blocks_count) { + int rc = ext4_extent_release_blocks_from( + inode_ref, + new_blocks_count); + if (rc != EOK) + return rc; + + } } else #endif { @@ -934,9 +935,9 @@ int ext4_fs_truncate_inode(struct ext4_inode_ref *inode_ref, uint64_t new_size) /* Starting from 1 because of logical blocks are numbered from 0 */ - for (i = 1; i <= diff_blocks_count; ++i) { + for (i = 0; i < diff_blocks_count; ++i) { int rc = ext4_fs_release_inode_block( - inode_ref, old_blocks_count - i); + inode_ref, new_blocks_count + i); if (rc != EOK) return rc; }