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