summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJin Qian <jinqian@google.com>2017-09-07 17:09:45 -0700
committerTao Bao <tbao@google.com>2017-09-11 12:15:14 -0700
commit98e42725761e4df326851f08a491f553619debdf (patch)
tree9f77c29fdb7599f413181f1a9fea9081b48ff5ee
parent0a26d1b8937ba3c4fda6f66e57cd418e314affba (diff)
downloadextras-98e42725761e4df326851f08a491f553619debdf.tar.gz
ext4_utils: fix off-by-one error when free blocks
block points at one block before the region we wanted to free after the loop that updats bitmap. This causes the code to free chunk still being used. Bug: 35262536 Test: lunch angler-userdebug; m dist Test: lunch bullhead-userdebug; m dist Change-Id: I7ebb30f4c7bcd01d3213ae0804a026a5ad98072c (cherry picked from commit a4ed4e10e98b0efa4e259c99e84609bebb08cd66)
-rw-r--r--ext4_utils/allocate.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/ext4_utils/allocate.c b/ext4_utils/allocate.c
index 28fc8e50..6bd77fa5 100644
--- a/ext4_utils/allocate.c
+++ b/ext4_utils/allocate.c
@@ -231,16 +231,20 @@ static int reserve_blocks(struct block_group_info *bg, u32 bg_num, u32 start, u3
static void free_blocks(struct block_group_info *bg, u32 block, u32 num_blocks)
{
unsigned int i;
+
+ if (num_blocks == 0)
+ return;
for (i = 0; i < num_blocks; i++, block--)
bg->block_bitmap[block / 8] &= ~(1 << (block % 8));
bg->free_blocks += num_blocks;
+ block++;
for (i = bg->chunk_count; i > 0 ;) {
--i;
if (bg->chunks[i].len >= num_blocks && bg->chunks[i].block <= block) {
if (bg->chunks[i].block == block) {
bg->chunks[i].block += num_blocks;
bg->chunks[i].len -= num_blocks;
- } else if (bg->chunks[i].block + bg->chunks[i].len - 1 == block + num_blocks) {
+ } else if (bg->chunks[i].block + bg->chunks[i].len == block + num_blocks) {
bg->chunks[i].len -= num_blocks;
}
break;