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