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