Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "ext4_utils.h"
     18 #include "allocate.h"
     19 
     20 #include <sparse/sparse.h>
     21 
     22 #include <stdio.h>
     23 #include <stdlib.h>
     24 
     25 struct region_list {
     26 	struct region *first;
     27 	struct region *last;
     28 	struct region *iter;
     29 	u32 partial_iter;
     30 };
     31 
     32 struct block_allocation {
     33 	struct region_list list;
     34 	struct region_list oob_list;
     35 };
     36 
     37 struct region {
     38 	u32 block;
     39 	u32 len;
     40 	int bg;
     41 	struct region *next;
     42 	struct region *prev;
     43 };
     44 
     45 struct block_group_info {
     46 	u32 first_block;
     47 	int header_blocks;
     48 	int data_blocks_used;
     49 	int has_superblock;
     50 	u8 *bitmaps;
     51 	u8 *block_bitmap;
     52 	u8 *inode_bitmap;
     53 	u8 *inode_table;
     54 	u32 free_blocks;
     55 	u32 first_free_block;
     56 	u32 free_inodes;
     57 	u32 first_free_inode;
     58 	u16 flags;
     59 	u16 used_dirs;
     60 };
     61 
     62 struct xattr_list_element {
     63 	struct ext4_inode *inode;
     64 	struct ext4_xattr_header *header;
     65 	struct xattr_list_element *next;
     66 };
     67 
     68 struct block_allocation *create_allocation()
     69 {
     70 	struct block_allocation *alloc = malloc(sizeof(struct block_allocation));
     71 	alloc->list.first = NULL;
     72 	alloc->list.last = NULL;
     73 	alloc->oob_list.first = NULL;
     74 	alloc->oob_list.last = NULL;
     75 	alloc->list.iter = NULL;
     76 	alloc->list.partial_iter = 0;
     77 	alloc->oob_list.iter = NULL;
     78 	alloc->oob_list.partial_iter = 0;
     79 	return alloc;
     80 }
     81 
     82 static struct ext4_xattr_header *xattr_list_find(struct ext4_inode *inode)
     83 {
     84 	struct xattr_list_element *element;
     85 	for (element = aux_info.xattrs; element != NULL; element = element->next) {
     86 		if (element->inode == inode)
     87 			return element->header;
     88 	}
     89 	return NULL;
     90 }
     91 
     92 static void xattr_list_insert(struct ext4_inode *inode, struct ext4_xattr_header *header)
     93 {
     94 	struct xattr_list_element *element = malloc(sizeof(struct xattr_list_element));
     95 	element->inode = inode;
     96 	element->header = header;
     97 	element->next = aux_info.xattrs;
     98 	aux_info.xattrs = element;
     99 }
    100 
    101 static void region_list_remove(struct region_list *list, struct region *reg)
    102 {
    103 	if (reg->prev)
    104 		reg->prev->next = reg->next;
    105 
    106 	if (reg->next)
    107 		reg->next->prev = reg->prev;
    108 
    109 	if (list->first == reg)
    110 		list->first = reg->next;
    111 
    112 	if (list->last == reg)
    113 		list->last = reg->prev;
    114 
    115 	reg->next = NULL;
    116 	reg->prev = NULL;
    117 }
    118 
    119 static void region_list_append(struct region_list *list, struct region *reg)
    120 {
    121 	if (list->first == NULL) {
    122 		list->first = reg;
    123 		list->last = reg;
    124 		list->iter = reg;
    125 		list->partial_iter = 0;
    126 		reg->prev = NULL;
    127 	} else {
    128 		list->last->next = reg;
    129 		reg->prev = list->last;
    130 		list->last = reg;
    131 	}
    132 	reg->next = NULL;
    133 }
    134 
    135 #if 0
    136 static void dump_starting_from(struct region *reg)
    137 {
    138 	for (; reg; reg = reg->next) {
    139 		printf("%p: Blocks %d-%d (%d)\n", reg,
    140 				reg->bg * info.blocks_per_group + reg->block,
    141 				reg->bg * info.blocks_per_group + reg->block + reg->len - 1,
    142 				reg->len);
    143 	}
    144 }
    145 
    146 static void dump_region_lists(struct block_allocation *alloc) {
    147 
    148 	printf("Main list:\n");
    149 	dump_starting_from(alloc->list.first);
    150 
    151 	printf("OOB list:\n");
    152 	dump_starting_from(alloc->oob_list.first);
    153 }
    154 #endif
    155 
    156 void append_region(struct block_allocation *alloc,
    157 		u32 block, u32 len, int bg_num)
    158 {
    159 	struct region *reg;
    160 	reg = malloc(sizeof(struct region));
    161 	reg->block = block;
    162 	reg->len = len;
    163 	reg->bg = bg_num;
    164 	reg->next = NULL;
    165 
    166 	region_list_append(&alloc->list, reg);
    167 }
    168 
    169 static void allocate_bg_inode_table(struct block_group_info *bg)
    170 {
    171 	if (bg->inode_table != NULL)
    172 		return;
    173 
    174 	u32 block = bg->first_block + 2;
    175 
    176 	if (bg->has_superblock)
    177 		block += aux_info.bg_desc_blocks + info.bg_desc_reserve_blocks + 1;
    178 
    179 	bg->inode_table = calloc(aux_info.inode_table_blocks, info.block_size);
    180 	if (bg->inode_table == NULL)
    181 		critical_error_errno("calloc");
    182 
    183 	sparse_file_add_data(ext4_sparse_file, bg->inode_table,
    184 			aux_info.inode_table_blocks	* info.block_size, block);
    185 
    186 	bg->flags &= ~EXT4_BG_INODE_UNINIT;
    187 }
    188 
    189 static int bitmap_set_bit(u8 *bitmap, u32 bit)
    190 {
    191 	if (bitmap[bit / 8] & 1 << (bit % 8))
    192 		return 1;
    193 
    194 	bitmap[bit / 8] |= 1 << (bit % 8);
    195 	return 0;
    196 }
    197 
    198 static int bitmap_set_8_bits(u8 *bitmap, u32 bit)
    199 {
    200 	int ret = bitmap[bit / 8];
    201 	bitmap[bit / 8] = 0xFF;
    202 	return ret;
    203 }
    204 
    205 /* Marks a the first num_blocks blocks in a block group as used, and accounts
    206  for them in the block group free block info. */
    207 static int reserve_blocks(struct block_group_info *bg, u32 start, u32 num)
    208 {
    209 	unsigned int i = 0;
    210 
    211 	u32 block = start;
    212 	if (num > bg->free_blocks)
    213 		return -1;
    214 
    215 	for (i = 0; i < num && block % 8 != 0; i++, block++) {
    216 		if (bitmap_set_bit(bg->block_bitmap, block)) {
    217 			error("attempted to reserve already reserved block");
    218 			return -1;
    219 		}
    220 	}
    221 
    222 	for (; i + 8 <= (num & ~7); i += 8, block += 8) {
    223 		if (bitmap_set_8_bits(bg->block_bitmap, block)) {
    224 			error("attempted to reserve already reserved block");
    225 			return -1;
    226 		}
    227 	}
    228 
    229 	for (; i < num; i++, block++) {
    230 		if (bitmap_set_bit(bg->block_bitmap, block)) {
    231 			error("attempted to reserve already reserved block");
    232 			return -1;
    233 		}
    234 	}
    235 
    236 	bg->free_blocks -= num;
    237 	if (start == bg->first_free_block)
    238 		bg->first_free_block = start + num;
    239 
    240 	return 0;
    241 }
    242 
    243 static void free_blocks(struct block_group_info *bg, u32 num_blocks)
    244 {
    245 	unsigned int i;
    246 	u32 block = bg->first_free_block - 1;
    247 	for (i = 0; i < num_blocks; i++, block--)
    248 		bg->block_bitmap[block / 8] &= ~(1 << (block % 8));
    249 	bg->free_blocks += num_blocks;
    250 	bg->first_free_block -= num_blocks;
    251 }
    252 
    253 /* Reduces an existing allocation by len blocks by return the last blocks
    254    to the free pool in their block group. Assumes that the blocks being
    255    returned were the last ones allocated out of the block group */
    256 void reduce_allocation(struct block_allocation *alloc, u32 len)
    257 {
    258 	while (len) {
    259 		struct region *last_reg = alloc->list.last;
    260 
    261 		if (last_reg->len > len) {
    262 			free_blocks(&aux_info.bgs[last_reg->bg], len);
    263 			last_reg->len -= len;
    264 			len = 0;
    265 		} else {
    266 			struct region *reg = alloc->list.last->prev;
    267 			free_blocks(&aux_info.bgs[last_reg->bg], last_reg->len);
    268 			len -= last_reg->len;
    269 			if (reg) {
    270 				reg->next = NULL;
    271 			} else {
    272 				alloc->list.first = NULL;
    273 				alloc->list.last = NULL;
    274 				alloc->list.iter = NULL;
    275 				alloc->list.partial_iter = 0;
    276 			}
    277 			free(last_reg);
    278 		}
    279 	}
    280 }
    281 
    282 static void init_bg(struct block_group_info *bg, unsigned int i)
    283 {
    284 	int header_blocks = 2 + aux_info.inode_table_blocks;
    285 
    286 	bg->has_superblock = ext4_bg_has_super_block(i);
    287 
    288 	if (bg->has_superblock)
    289 		header_blocks += 1 + aux_info.bg_desc_blocks + info.bg_desc_reserve_blocks;
    290 
    291 	bg->bitmaps = calloc(info.block_size, 2);
    292 	bg->block_bitmap = bg->bitmaps;
    293 	bg->inode_bitmap = bg->bitmaps + info.block_size;
    294 
    295 	bg->header_blocks = header_blocks;
    296 	bg->first_block = aux_info.first_data_block + i * info.blocks_per_group;
    297 
    298 	u32 block = bg->first_block;
    299 	if (bg->has_superblock)
    300 		block += 1 + aux_info.bg_desc_blocks +  info.bg_desc_reserve_blocks;
    301 	sparse_file_add_data(ext4_sparse_file, bg->bitmaps, 2 * info.block_size,
    302 			block);
    303 
    304 	bg->data_blocks_used = 0;
    305 	bg->free_blocks = info.blocks_per_group;
    306 	bg->first_free_block = 0;
    307 	bg->free_inodes = info.inodes_per_group;
    308 	bg->first_free_inode = 1;
    309 	bg->flags = EXT4_BG_INODE_UNINIT;
    310 
    311 	if (reserve_blocks(bg, bg->first_free_block, bg->header_blocks) < 0)
    312 		error("failed to reserve %u blocks in block group %u\n", bg->header_blocks, i);
    313 
    314 	if (bg->first_block + info.blocks_per_group > aux_info.len_blocks) {
    315 		u32 overrun = bg->first_block + info.blocks_per_group - aux_info.len_blocks;
    316 		reserve_blocks(bg, info.blocks_per_group - overrun, overrun);
    317 	}
    318 }
    319 
    320 void block_allocator_init()
    321 {
    322 	unsigned int i;
    323 
    324 	aux_info.bgs = calloc(sizeof(struct block_group_info), aux_info.groups);
    325 	if (aux_info.bgs == NULL)
    326 		critical_error_errno("calloc");
    327 
    328 	for (i = 0; i < aux_info.groups; i++)
    329 		init_bg(&aux_info.bgs[i], i);
    330 }
    331 
    332 void block_allocator_free()
    333 {
    334 	unsigned int i;
    335 
    336 	for (i = 0; i < aux_info.groups; i++) {
    337 		free(aux_info.bgs[i].bitmaps);
    338 		free(aux_info.bgs[i].inode_table);
    339 	}
    340 	free(aux_info.bgs);
    341 }
    342 
    343 static u32 ext4_allocate_blocks_from_block_group(u32 len, int bg_num)
    344 {
    345 	if (get_free_blocks(bg_num) < len)
    346 		return EXT4_ALLOCATE_FAILED;
    347 
    348 	u32 block = aux_info.bgs[bg_num].first_free_block;
    349 	struct block_group_info *bg = &aux_info.bgs[bg_num];
    350 	if (reserve_blocks(bg, bg->first_free_block, len) < 0) {
    351 		error("failed to reserve %u blocks in block group %u\n", len, bg_num);
    352 		return EXT4_ALLOCATE_FAILED;
    353 	}
    354 
    355 	aux_info.bgs[bg_num].data_blocks_used += len;
    356 
    357 	return bg->first_block + block;
    358 }
    359 
    360 /* Allocate a single block and return its block number */
    361 u32 allocate_block()
    362 {
    363 	unsigned int i;
    364 	for (i = 0; i < aux_info.groups; i++) {
    365 		u32 block = ext4_allocate_blocks_from_block_group(1, i);
    366 
    367 		if (block != EXT4_ALLOCATE_FAILED)
    368 			return block;
    369 	}
    370 
    371 	return EXT4_ALLOCATE_FAILED;
    372 }
    373 
    374 static struct region *ext4_allocate_best_fit_partial(u32 len)
    375 {
    376 	unsigned int i;
    377 	unsigned int found_bg = 0;
    378 	u32 found_bg_len = 0;
    379 
    380 	for (i = 0; i < aux_info.groups; i++) {
    381 		u32 bg_len = aux_info.bgs[i].free_blocks;
    382 
    383 		if ((len <= bg_len && (found_bg_len == 0 || bg_len < found_bg_len)) ||
    384 		    (len > found_bg_len && bg_len > found_bg_len)) {
    385 			found_bg = i;
    386 			found_bg_len = bg_len;
    387 		}
    388 	}
    389 
    390 	if (found_bg_len) {
    391 		u32 allocate_len = min(len, found_bg_len);
    392 		struct region *reg;
    393 		u32 block = ext4_allocate_blocks_from_block_group(allocate_len, found_bg);
    394 		if (block == EXT4_ALLOCATE_FAILED) {
    395 			error("failed to allocate %d blocks in block group %d", allocate_len, found_bg);
    396 			return NULL;
    397 		}
    398 		reg = malloc(sizeof(struct region));
    399 		reg->block = block;
    400 		reg->len = allocate_len;
    401 		reg->next = NULL;
    402 		reg->prev = NULL;
    403 		reg->bg = found_bg;
    404 		return reg;
    405 	} else {
    406 		error("failed to allocate %u blocks, out of space?", len);
    407 	}
    408 
    409 	return NULL;
    410 }
    411 
    412 static struct region *ext4_allocate_best_fit(u32 len)
    413 {
    414 	struct region *first_reg = NULL;
    415 	struct region *prev_reg = NULL;
    416 	struct region *reg;
    417 
    418 	while (len > 0) {
    419 		reg = ext4_allocate_best_fit_partial(len);
    420 		if (reg == NULL)
    421 			return NULL;
    422 
    423 		if (first_reg == NULL)
    424 			first_reg = reg;
    425 
    426 		if (prev_reg) {
    427 			prev_reg->next = reg;
    428 			reg->prev = prev_reg;
    429 		}
    430 
    431 		prev_reg = reg;
    432 		len -= reg->len;
    433 	}
    434 
    435 	return first_reg;
    436 }
    437 
    438 /* Allocate len blocks.  The blocks may be spread across multiple block groups,
    439    and are returned in a linked list of the blocks in each block group.  The
    440    allocation algorithm is:
    441       1.  If the remaining allocation is larger than any available contiguous region,
    442           allocate the largest contiguous region and loop
    443       2.  Otherwise, allocate the smallest contiguous region that it fits in
    444 */
    445 struct block_allocation *allocate_blocks(u32 len)
    446 {
    447 	struct region *reg = ext4_allocate_best_fit(len);
    448 
    449 	if (reg == NULL)
    450 		return NULL;
    451 
    452 	struct block_allocation *alloc = create_allocation();
    453 	alloc->list.first = reg;
    454 	alloc->list.last = reg;
    455 	alloc->list.iter = alloc->list.first;
    456 	alloc->list.partial_iter = 0;
    457 	return alloc;
    458 }
    459 
    460 /* Returns the number of discontiguous regions used by an allocation */
    461 int block_allocation_num_regions(struct block_allocation *alloc)
    462 {
    463 	unsigned int i;
    464 	struct region *reg = alloc->list.first;
    465 
    466 	for (i = 0; reg != NULL; reg = reg->next)
    467 		i++;
    468 
    469 	return i;
    470 }
    471 
    472 int block_allocation_len(struct block_allocation *alloc)
    473 {
    474 	unsigned int i;
    475 	struct region *reg = alloc->list.first;
    476 
    477 	for (i = 0; reg != NULL; reg = reg->next)
    478 		i += reg->len;
    479 
    480 	return i;
    481 }
    482 
    483 /* Returns the block number of the block'th block in an allocation */
    484 u32 get_block(struct block_allocation *alloc, u32 block)
    485 {
    486 	struct region *reg = alloc->list.iter;
    487 	block += alloc->list.partial_iter;
    488 
    489 	for (; reg; reg = reg->next) {
    490 		if (block < reg->len)
    491 			return reg->block + block;
    492 		block -= reg->len;
    493 	}
    494 	return EXT4_ALLOCATE_FAILED;
    495 }
    496 
    497 u32 get_oob_block(struct block_allocation *alloc, u32 block)
    498 {
    499 	struct region *reg = alloc->oob_list.iter;
    500 	block += alloc->oob_list.partial_iter;
    501 
    502 	for (; reg; reg = reg->next) {
    503 		if (block < reg->len)
    504 			return reg->block + block;
    505 		block -= reg->len;
    506 	}
    507 	return EXT4_ALLOCATE_FAILED;
    508 }
    509 
    510 /* Gets the starting block and length in blocks of the first region
    511    of an allocation */
    512 void get_region(struct block_allocation *alloc, u32 *block, u32 *len)
    513 {
    514 	*block = alloc->list.iter->block;
    515 	*len = alloc->list.iter->len - alloc->list.partial_iter;
    516 }
    517 
    518 /* Move to the next region in an allocation */
    519 void get_next_region(struct block_allocation *alloc)
    520 {
    521 	alloc->list.iter = alloc->list.iter->next;
    522 	alloc->list.partial_iter = 0;
    523 }
    524 
    525 /* Returns the number of free blocks in a block group */
    526 u32 get_free_blocks(u32 bg)
    527 {
    528 	return aux_info.bgs[bg].free_blocks;
    529 }
    530 
    531 int last_region(struct block_allocation *alloc)
    532 {
    533 	return (alloc->list.iter == NULL);
    534 }
    535 
    536 void rewind_alloc(struct block_allocation *alloc)
    537 {
    538 	alloc->list.iter = alloc->list.first;
    539 	alloc->list.partial_iter = 0;
    540 }
    541 
    542 static struct region *do_split_allocation(struct block_allocation *alloc, u32 len)
    543 {
    544 	struct region *reg = alloc->list.iter;
    545 	struct region *new;
    546 	struct region *tmp;
    547 
    548 	while (reg && len >= reg->len) {
    549 		len -= reg->len;
    550 		reg = reg->next;
    551 	}
    552 
    553 	if (reg == NULL && len > 0)
    554 		return NULL;
    555 
    556 	if (len > 0) {
    557 		new = malloc(sizeof(struct region));
    558 
    559 		new->bg = reg->bg;
    560 		new->block = reg->block + len;
    561 		new->len = reg->len - len;
    562 		new->next = reg->next;
    563 		new->prev = reg;
    564 
    565 		reg->next = new;
    566 		reg->len = len;
    567 
    568 		tmp = alloc->list.iter;
    569 		alloc->list.iter = new;
    570 		return tmp;
    571 	} else {
    572 		return reg;
    573 	}
    574 }
    575 
    576 /* Splits an allocation into two allocations.  The returned allocation will
    577    point to the first half, and the original allocation ptr will point to the
    578    second half. */
    579 static struct region *split_allocation(struct block_allocation *alloc, u32 len)
    580 {
    581 	/* First make sure there is a split at the current ptr */
    582 	do_split_allocation(alloc, alloc->list.partial_iter);
    583 
    584 	/* Then split off len blocks */
    585 	struct region *middle = do_split_allocation(alloc, len);
    586 	alloc->list.partial_iter = 0;
    587 	return middle;
    588 }
    589 
    590 /* Reserve the next blocks for oob data (indirect or extent blocks) */
    591 int reserve_oob_blocks(struct block_allocation *alloc, int blocks)
    592 {
    593 	struct region *oob = split_allocation(alloc, blocks);
    594 	struct region *next;
    595 
    596 	if (oob == NULL)
    597 		return -1;
    598 
    599 	while (oob && oob != alloc->list.iter) {
    600 		next = oob->next;
    601 		region_list_remove(&alloc->list, oob);
    602 		region_list_append(&alloc->oob_list, oob);
    603 		oob = next;
    604 	}
    605 
    606 	return 0;
    607 }
    608 
    609 static int advance_list_ptr(struct region_list *list, int blocks)
    610 {
    611 	struct region *reg = list->iter;
    612 
    613 	while (reg != NULL && blocks > 0) {
    614 		if (reg->len > list->partial_iter + blocks) {
    615 			list->partial_iter += blocks;
    616 			return 0;
    617 		}
    618 
    619 		blocks -= (reg->len - list->partial_iter);
    620 		list->partial_iter = 0;
    621 		reg = reg->next;
    622 	}
    623 
    624 	if (blocks > 0)
    625 		return -1;
    626 
    627 	return 0;
    628 }
    629 
    630 /* Move the allocation pointer forward */
    631 int advance_blocks(struct block_allocation *alloc, int blocks)
    632 {
    633 	return advance_list_ptr(&alloc->list, blocks);
    634 }
    635 
    636 int advance_oob_blocks(struct block_allocation *alloc, int blocks)
    637 {
    638 	return advance_list_ptr(&alloc->oob_list, blocks);
    639 }
    640 
    641 int append_oob_allocation(struct block_allocation *alloc, u32 len)
    642 {
    643 	struct region *reg = ext4_allocate_best_fit(len);
    644 
    645 	if (reg == NULL) {
    646 		error("failed to allocate %d blocks", len);
    647 		return -1;
    648 	}
    649 
    650 	for (; reg; reg = reg->next)
    651 		region_list_append(&alloc->oob_list, reg);
    652 
    653 	return 0;
    654 }
    655 
    656 /* Returns an ext4_inode structure for an inode number */
    657 struct ext4_inode *get_inode(u32 inode)
    658 {
    659 	inode -= 1;
    660 	int bg = inode / info.inodes_per_group;
    661 	inode %= info.inodes_per_group;
    662 
    663 	allocate_bg_inode_table(&aux_info.bgs[bg]);
    664 	return (struct ext4_inode *)(aux_info.bgs[bg].inode_table + inode *
    665 		info.inode_size);
    666 }
    667 
    668 struct ext4_xattr_header *get_xattr_block_for_inode(struct ext4_inode *inode)
    669 {
    670 	struct ext4_xattr_header *block = xattr_list_find(inode);
    671 	if (block != NULL)
    672 		return block;
    673 
    674 	u32 block_num = allocate_block();
    675 	block = calloc(info.block_size, 1);
    676 	if (block == NULL) {
    677 		error("get_xattr: failed to allocate %d", info.block_size);
    678 		return NULL;
    679 	}
    680 
    681 	block->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC);
    682 	block->h_refcount = cpu_to_le32(1);
    683 	block->h_blocks = cpu_to_le32(1);
    684 	inode->i_blocks_lo = cpu_to_le32(le32_to_cpu(inode->i_blocks_lo) + (info.block_size / 512));
    685 	inode->i_file_acl_lo = cpu_to_le32(block_num);
    686 
    687 	int result = sparse_file_add_data(ext4_sparse_file, block, info.block_size, block_num);
    688 	if (result != 0) {
    689 		error("get_xattr: sparse_file_add_data failure %d", result);
    690 		free(block);
    691 		return NULL;
    692 	}
    693 	xattr_list_insert(inode, block);
    694 	return block;
    695 }
    696 
    697 /* Mark the first len inodes in a block group as used */
    698 u32 reserve_inodes(int bg, u32 num)
    699 {
    700 	unsigned int i;
    701 	u32 inode;
    702 
    703 	if (get_free_inodes(bg) < num)
    704 		return EXT4_ALLOCATE_FAILED;
    705 
    706 	for (i = 0; i < num; i++) {
    707 		inode = aux_info.bgs[bg].first_free_inode + i - 1;
    708 		aux_info.bgs[bg].inode_bitmap[inode / 8] |= 1 << (inode % 8);
    709 	}
    710 
    711 	inode = aux_info.bgs[bg].first_free_inode;
    712 
    713 	aux_info.bgs[bg].first_free_inode += num;
    714 	aux_info.bgs[bg].free_inodes -= num;
    715 
    716 	return inode;
    717 }
    718 
    719 /* Returns the first free inode number
    720    TODO: Inodes should be allocated in the block group of the data? */
    721 u32 allocate_inode()
    722 {
    723 	unsigned int bg;
    724 	u32 inode;
    725 
    726 	for (bg = 0; bg < aux_info.groups; bg++) {
    727 		inode = reserve_inodes(bg, 1);
    728 		if (inode != EXT4_ALLOCATE_FAILED)
    729 			return bg * info.inodes_per_group + inode;
    730 	}
    731 
    732 	return EXT4_ALLOCATE_FAILED;
    733 }
    734 
    735 /* Returns the number of free inodes in a block group */
    736 u32 get_free_inodes(u32 bg)
    737 {
    738 	return aux_info.bgs[bg].free_inodes;
    739 }
    740 
    741 /* Increments the directory count of the block group that contains inode */
    742 void add_directory(u32 inode)
    743 {
    744 	int bg = (inode - 1) / info.inodes_per_group;
    745 	aux_info.bgs[bg].used_dirs += 1;
    746 }
    747 
    748 /* Returns the number of inodes in a block group that are directories */
    749 u16 get_directories(int bg)
    750 {
    751 	return aux_info.bgs[bg].used_dirs;
    752 }
    753 
    754 /* Returns the flags for a block group */
    755 u16 get_bg_flags(int bg)
    756 {
    757 	return aux_info.bgs[bg].flags;
    758 }
    759 
    760 /* Frees the memory used by a linked list of allocation regions */
    761 void free_alloc(struct block_allocation *alloc)
    762 {
    763 	struct region *reg;
    764 
    765 	reg = alloc->list.first;
    766 	while (reg) {
    767 		struct region *next = reg->next;
    768 		free(reg);
    769 		reg = next;
    770 	}
    771 
    772 	reg = alloc->oob_list.first;
    773 	while (reg) {
    774 		struct region *next = reg->next;
    775 		free(reg);
    776 		reg = next;
    777 	}
    778 
    779 	free(alloc);
    780 }
    781