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 26 struct region_list { 27 struct region *first; 28 struct region *last; 29 struct region *iter; 30 u32 partial_iter; 31 }; 32 33 struct block_allocation { 34 struct region_list list; 35 struct region_list oob_list; 36 }; 37 38 struct region { 39 u32 block; 40 u32 len; 41 int bg; 42 struct region *next; 43 struct region *prev; 44 }; 45 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 used_dirs; 60 }; 61 62 struct 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 76 static 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 94 static 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 111 static 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 121 static 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 131 void 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 144 static 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 162 void 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 180 static 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 189 static 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. */ 198 static 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 234 static 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 */ 247 void 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 273 static 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 309 void 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 321 void 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 332 static 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 349 static 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 */ 372 u32 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 385 static 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 423 static 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 449 struct 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 */ 467 struct 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 */ 483 int 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 494 int 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 */ 506 u32 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 519 u32 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 */ 534 void 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 */ 541 void 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 */ 548 u32 get_free_blocks(u32 bg) 549 { 550 return aux_info.bgs[bg].free_blocks; 551 } 552 553 int last_region(struct block_allocation *alloc) 554 { 555 return (alloc->list.iter == NULL); 556 } 557 558 void rewind_alloc(struct block_allocation *alloc) 559 { 560 alloc->list.iter = alloc->list.first; 561 alloc->list.partial_iter = 0; 562 } 563 564 static 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. */ 601 static 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) */ 613 int 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 631 static 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 */ 653 int advance_blocks(struct block_allocation *alloc, int blocks) 654 { 655 return advance_list_ptr(&alloc->list, blocks); 656 } 657 658 int advance_oob_blocks(struct block_allocation *alloc, int blocks) 659 { 660 return advance_list_ptr(&alloc->oob_list, blocks); 661 } 662 663 int 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 */ 679 struct 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 */ 691 u32 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? */ 714 u32 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 */ 729 u32 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 */ 735 void 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 */ 742 u16 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 */ 748 void 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