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