diff options
author | Jin Qian <jinqian@google.com> | 2017-09-07 17:09:45 -0700 |
---|---|---|
committer | Tao Bao <tbao@google.com> | 2017-09-11 12:15:14 -0700 |
commit | 98e42725761e4df326851f08a491f553619debdf (patch) | |
tree | 9f77c29fdb7599f413181f1a9fea9081b48ff5ee | |
parent | 0a26d1b8937ba3c4fda6f66e57cd418e314affba (diff) | |
download | extras-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.c | 6 |
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; |