ref: 65feb6cfe7d59d7d9e48dffa1fbac056bd557266
parent: 92053fed4a3c6e17c0c1c7596353c8c5465bdf1f
parent: d526904e82411b27f878e245b74a0411e3a8ea32
author: gkostka <kostka.grzegorz@gmail.com>
date: Sun Sep 27 04:02:51 EDT 2015
Merge pull request #6 from ngkaho1234/master FIX: an extra block is freed when truncating an inode.
--- a/lwext4/ext4_fs.c
+++ b/lwext4/ext4_fs.c
@@ -908,15 +908,12 @@
}
/* 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)) &&
@@ -923,10 +920,14 @@
(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 @@
/* 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;
}