Skip to content

Commit 18785a8

Browse files
committed
Revert "Redesign make_ext4fs to incrementally generate ext4 images"
This reverts commit 3d96084. Change-Id: I0fb7d65f094feb4013924685270fc847693b6889
1 parent 3d96084 commit 18785a8

File tree

8 files changed

+130
-361
lines changed

8 files changed

+130
-361
lines changed

ext4_utils/allocate.c

Lines changed: 91 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -22,6 +22,31 @@
2222
#include <stdio.h>
2323
#include <stdlib.h>
2424

25+
struct region {
26+
u32 block;
27+
u32 len;
28+
int bg;
29+
struct region *next;
30+
struct region *prev;
31+
};
32+
33+
struct block_group_info {
34+
u32 first_block;
35+
int header_blocks;
36+
int data_blocks_used;
37+
int has_superblock;
38+
u8 *bitmaps;
39+
u8 *block_bitmap;
40+
u8 *inode_bitmap;
41+
u8 *inode_table;
42+
u32 free_blocks;
43+
u32 first_free_block;
44+
u32 free_inodes;
45+
u32 first_free_inode;
46+
u16 flags;
47+
u16 used_dirs;
48+
};
49+
2550
struct xattr_list_element {
2651
struct ext4_inode *inode;
2752
struct ext4_xattr_header *header;
@@ -81,7 +106,7 @@ static void region_list_remove(struct region_list *list, struct region *reg)
81106
reg->prev = NULL;
82107
}
83108

84-
void region_list_append(struct region_list *list, struct region *reg)
109+
static void region_list_append(struct region_list *list, struct region *reg)
85110
{
86111
if (list->first == NULL) {
87112
list->first = reg;
@@ -119,12 +144,11 @@ static void dump_region_lists(struct block_allocation *alloc) {
119144
void print_blocks(FILE* f, struct block_allocation *alloc)
120145
{
121146
struct region *reg;
122-
fputc(' ', f);
123147
for (reg = alloc->list.first; reg; reg = reg->next) {
124148
if (reg->len == 1) {
125-
fprintf(f, "%d,", reg->block);
149+
fprintf(f, " %d", reg->block);
126150
} else {
127-
fprintf(f, "%d-%d,", reg->block, reg->block + reg->len - 1);
151+
fprintf(f, " %d-%d", reg->block, reg->block + reg->len - 1);
128152
}
129153
}
130154
fputc('\n', f);
@@ -186,23 +210,26 @@ static int reserve_blocks(struct block_group_info *bg, u32 start, u32 num)
186210
unsigned int i = 0;
187211

188212
u32 block = start;
213+
if (num > bg->free_blocks)
214+
return -1;
215+
189216
for (i = 0; i < num && block % 8 != 0; i++, block++) {
190217
if (bitmap_set_bit(bg->block_bitmap, block)) {
191-
error("attempted to reserve already reserved block %d and num is %d", block, num);
218+
error("attempted to reserve already reserved block");
192219
return -1;
193220
}
194221
}
195222

196223
for (; i + 8 <= (num & ~7); i += 8, block += 8) {
197224
if (bitmap_set_8_bits(bg->block_bitmap, block)) {
198-
error("attempted to reserve already reserved block %d and num is %d", block, num);
225+
error("attempted to reserve already reserved block");
199226
return -1;
200227
}
201228
}
202229

203230
for (; i < num; i++, block++) {
204231
if (bitmap_set_bit(bg->block_bitmap, block)) {
205-
error("attempted to reserve already reserved block %d and num is %d", block, num);
232+
error("attempted to reserve already reserved block");
206233
return -1;
207234
}
208235
}
@@ -282,24 +309,13 @@ static void init_bg(struct block_group_info *bg, unsigned int i)
282309
bg->first_free_inode = 1;
283310
bg->flags = 0;
284311

285-
bg->chunk_count = 0;
286-
bg->max_chunk_count = 1;
287-
bg->chunks = (struct region*) calloc(bg->max_chunk_count, sizeof(struct region));
288-
289312
if (reserve_blocks(bg, bg->first_free_block, bg->header_blocks) < 0)
290313
error("failed to reserve %u blocks in block group %u\n", bg->header_blocks, i);
291-
// Add empty starting delimiter chunk
292-
reserve_bg_chunk(i, bg->first_free_block, 0);
293314

294315
if (bg->first_block + info.blocks_per_group > aux_info.len_blocks) {
295316
u32 overrun = bg->first_block + info.blocks_per_group - aux_info.len_blocks;
296317
reserve_blocks(bg, info.blocks_per_group - overrun, overrun);
297-
// Add empty ending delimiter chunk
298-
reserve_bg_chunk(i, info.blocks_per_group - overrun, 0);
299-
} else {
300-
reserve_bg_chunk(i, info.blocks_per_group - 1, 0);
301318
}
302-
303319
}
304320

305321
void block_allocator_init()
@@ -325,78 +341,73 @@ void block_allocator_free()
325341
free(aux_info.bgs);
326342
}
327343

344+
static u32 ext4_allocate_blocks_from_block_group(u32 len, int bg_num)
345+
{
346+
if (get_free_blocks(bg_num) < len)
347+
return EXT4_ALLOCATE_FAILED;
348+
349+
u32 block = aux_info.bgs[bg_num].first_free_block;
350+
struct block_group_info *bg = &aux_info.bgs[bg_num];
351+
if (reserve_blocks(bg, bg->first_free_block, len) < 0) {
352+
error("failed to reserve %u blocks in block group %u\n", len, bg_num);
353+
return EXT4_ALLOCATE_FAILED;
354+
}
355+
356+
aux_info.bgs[bg_num].data_blocks_used += len;
357+
358+
return bg->first_block + block;
359+
}
360+
328361
/* Allocate a single block and return its block number */
329362
u32 allocate_block()
330363
{
331-
u32 block;
332-
struct block_allocation *blk_alloc = allocate_blocks(1);
333-
if (!blk_alloc) {
334-
return EXT4_ALLOCATE_FAILED;
364+
unsigned int i;
365+
for (i = 0; i < aux_info.groups; i++) {
366+
u32 block = ext4_allocate_blocks_from_block_group(1, i);
367+
368+
if (block != EXT4_ALLOCATE_FAILED)
369+
return block;
335370
}
336-
block = blk_alloc->list.first->block;
337-
free_alloc(blk_alloc);
338-
return block;
371+
372+
return EXT4_ALLOCATE_FAILED;
339373
}
340374

341375
static struct region *ext4_allocate_best_fit_partial(u32 len)
342376
{
343-
unsigned int i, j;
344-
unsigned int found_bg = 0, found_prev_chunk = 0, found_block = 0;
345-
u32 found_allocate_len = 0;
346-
bool minimize = false;
347-
struct block_group_info *bgs = aux_info.bgs;
348-
struct region *reg;
377+
unsigned int i;
378+
unsigned int found_bg = 0;
379+
u32 found_bg_len = 0;
380+
349381
for (i = 0; i < aux_info.groups; i++) {
350-
for (j = 1; j < bgs[i].chunk_count; j++) {
351-
u32 hole_start, hole_size;
352-
hole_start = bgs[i].chunks[j-1].block + bgs[i].chunks[j-1].len;
353-
hole_size = bgs[i].chunks[j].block - hole_start;
354-
if (hole_size == len) {
355-
// Perfect fit i.e. right between 2 chunks no need to keep searching
356-
found_bg = i;
357-
found_prev_chunk = j - 1;
358-
found_block = hole_start;
359-
found_allocate_len = hole_size;
360-
goto done;
361-
} else if (hole_size > len && (found_allocate_len == 0 || (found_allocate_len > hole_size))) {
362-
found_bg = i;
363-
found_prev_chunk = j - 1;
364-
found_block = hole_start;
365-
found_allocate_len = hole_size;
366-
minimize = true;
367-
} else if (!minimize) {
368-
if (found_allocate_len < hole_size) {
369-
found_bg = i;
370-
found_prev_chunk = j - 1;
371-
found_block = hole_start;
372-
found_allocate_len = hole_size;
373-
}
374-
}
382+
u32 bg_len = aux_info.bgs[i].free_blocks;
383+
384+
if ((len <= bg_len && (found_bg_len == 0 || bg_len < found_bg_len)) ||
385+
(len > found_bg_len && bg_len > found_bg_len)) {
386+
found_bg = i;
387+
found_bg_len = bg_len;
375388
}
376389
}
377390

378-
if (found_allocate_len == 0) {
391+
if (found_bg_len) {
392+
u32 allocate_len = min(len, found_bg_len);
393+
struct region *reg;
394+
u32 block = ext4_allocate_blocks_from_block_group(allocate_len, found_bg);
395+
if (block == EXT4_ALLOCATE_FAILED) {
396+
error("failed to allocate %d blocks in block group %d", allocate_len, found_bg);
397+
return NULL;
398+
}
399+
reg = malloc(sizeof(struct region));
400+
reg->block = block;
401+
reg->len = allocate_len;
402+
reg->next = NULL;
403+
reg->prev = NULL;
404+
reg->bg = found_bg;
405+
return reg;
406+
} else {
379407
error("failed to allocate %u blocks, out of space?", len);
380-
return NULL;
381408
}
382-
if (found_allocate_len > len) found_allocate_len = len;
383-
done:
384-
// reclaim allocated space in chunk
385-
bgs[found_bg].chunks[found_prev_chunk].len += found_allocate_len;
386-
if (reserve_blocks(&bgs[found_bg],
387-
found_block,
388-
found_allocate_len) < 0) {
389-
error("failed to reserve %u blocks in block group %u\n", found_allocate_len, found_bg);
390-
return NULL;
391-
}
392-
bgs[found_bg].data_blocks_used += found_allocate_len;
393-
reg = malloc(sizeof(struct region));
394-
reg->block = found_block + bgs[found_bg].first_block;
395-
reg->len = found_allocate_len;
396-
reg->next = NULL;
397-
reg->prev = NULL;
398-
reg->bg = found_bg;
399-
return reg;
409+
410+
return NULL;
400411
}
401412

402413
static struct region *ext4_allocate_best_fit(u32 len)
@@ -428,9 +439,9 @@ static struct region *ext4_allocate_best_fit(u32 len)
428439
/* Allocate len blocks. The blocks may be spread across multiple block groups,
429440
and are returned in a linked list of the blocks in each block group. The
430441
allocation algorithm is:
431-
1. If the remaining allocation is larger than any available contiguous region,
432-
allocate the largest contiguous region and loop
433-
2. Otherwise, allocate the smallest contiguous region that it fits in
442+
1. If the remaining allocation is larger than any available contiguous region,
443+
allocate the largest contiguous region and loop
444+
2. Otherwise, allocate the smallest contiguous region that it fits in
434445
*/
435446
struct block_allocation *allocate_blocks(u32 len)
436447
{
@@ -441,8 +452,6 @@ struct block_allocation *allocate_blocks(u32 len)
441452

442453
struct block_allocation *alloc = create_allocation();
443454
alloc->list.first = reg;
444-
while (reg->next != NULL)
445-
reg = reg->next;
446455
alloc->list.last = reg;
447456
alloc->list.iter = alloc->list.first;
448457
alloc->list.partial_iter = 0;
@@ -770,20 +779,3 @@ void free_alloc(struct block_allocation *alloc)
770779

771780
free(alloc);
772781
}
773-
774-
void reserve_bg_chunk(int bg, u32 start_block, u32 size) {
775-
struct block_group_info *bgs = aux_info.bgs;
776-
int chunk_count;
777-
if (bgs[bg].chunk_count == bgs[bg].max_chunk_count) {
778-
bgs[bg].max_chunk_count *= 2;
779-
bgs[bg].chunks = realloc(bgs[bg].chunks, bgs[bg].max_chunk_count * sizeof(struct region));
780-
if (!bgs[bg].chunks)
781-
critical_error("realloc failed");
782-
}
783-
chunk_count = bgs[bg].chunk_count;
784-
bgs[bg].chunks[chunk_count].block = start_block;
785-
bgs[bg].chunks[chunk_count].len = size;
786-
bgs[bg].chunks[chunk_count].bg = bg;
787-
bgs[bg].chunk_count++;
788-
}
789-

ext4_utils/allocate.h

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,7 @@
2121

2222
#include "ext4_utils.h"
2323

24-
struct region {
25-
u32 block;
26-
u32 len;
27-
int bg;
28-
struct region *next;
29-
struct region *prev;
30-
};
24+
struct region;
3125

3226
struct region_list {
3327
struct region *first;
@@ -43,25 +37,6 @@ struct block_allocation {
4337
struct block_allocation* next;
4438
};
4539

46-
struct block_group_info {
47-
u32 first_block;
48-
int header_blocks;
49-
int data_blocks_used;
50-
int has_superblock;
51-
u8 *bitmaps;
52-
u8 *block_bitmap;
53-
u8 *inode_bitmap;
54-
u8 *inode_table;
55-
u32 free_blocks;
56-
u32 first_free_block;
57-
u32 free_inodes;
58-
u32 first_free_inode;
59-
u16 flags;
60-
u16 used_dirs;
61-
int chunk_count;
62-
int max_chunk_count;
63-
struct region *chunks;
64-
};
6540

6641
void block_allocator_init();
6742
void block_allocator_free();
@@ -94,8 +69,6 @@ void append_region(struct block_allocation *alloc,
9469
u32 block, u32 len, int bg);
9570
struct block_allocation *create_allocation();
9671
int append_oob_allocation(struct block_allocation *alloc, u32 len);
97-
void region_list_append(struct region_list *list, struct region *reg);
9872
void print_blocks(FILE* f, struct block_allocation *alloc);
99-
void reserve_bg_chunk(int bg, u32 start_block, u32 size);
10073

10174
#endif

ext4_utils/ext4_utils.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ int force = 0;
4949
struct fs_info info;
5050
struct fs_aux_info aux_info;
5151
struct sparse_file *ext4_sparse_file;
52-
struct block_allocation *base_fs_allocations = NULL;
5352

5453
jmp_buf setjmp_env;
5554

ext4_utils/ext4_utils.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@ struct fs_aux_info {
119119
extern struct fs_info info;
120120
extern struct fs_aux_info aux_info;
121121
extern struct sparse_file *ext4_sparse_file;
122-
extern struct block_allocation *base_fs_allocations;
123122

124123
extern jmp_buf setjmp_env;
125124

@@ -162,7 +161,7 @@ int make_ext4fs_internal(int fd, const char *directory, const char *_target_out_
162161
const char *mountpoint, fs_config_func_t fs_config_func, int gzip,
163162
int sparse, int crc, int wipe, int real_uuid,
164163
struct selabel_handle *sehnd, int verbose, time_t fixed_time,
165-
FILE* block_list_file, FILE* base_fs_file);
164+
FILE* block_list_file);
166165

167166
int read_ext(int fd, int verbose);
168167

0 commit comments

Comments
 (0)