Changeset ee3b6150 in mainline
- Timestamp:
- 2012-04-23T16:01:14Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- bc03679
- Parents:
- 6773ff3
- Location:
- uspace/lib/ext4
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/ext4/libext4_extent.c
r6773ff3 ree3b6150 523 523 } 524 524 525 // TODO comments 526 527 // Recursive release 525 /** Recursively release the whole branch of the extent tree. 526 * 527 * For each entry of the node release the subbranch and finally release 528 * the node. In the leaf node all extents will be released. 529 * 530 * @param inode_ref i-node where the branch is released 531 * @param index index in the non-leaf node to be released 532 * with the whole subtree 533 * @return error code 534 */ 528 535 static int ext4_extent_release_branch(ext4_inode_ref_t *inode_ref, 529 536 ext4_extent_index_t *index) … … 534 541 535 542 uint32_t fblock = ext4_extent_index_get_leaf(index); 536 537 // EXT4FS_DBG("fblock = \%u", fblock);538 543 539 544 rc = block_get(&block, inode_ref->fs->device, fblock, BLOCK_FLAGS_NOREAD); … … 547 552 if (ext4_extent_header_get_depth(header)) { 548 553 554 // The node is non-leaf, do recursion 555 549 556 ext4_extent_index_t *idx = EXT4_EXTENT_FIRST_INDEX(header); 550 557 558 // Release all subbranches 551 559 for (uint32_t i = 0; i < ext4_extent_header_get_entries_count(header); ++i, ++idx) { 552 560 rc = ext4_extent_release_branch(inode_ref, idx); … … 557 565 } 558 566 } else { 567 568 // Leaf node reached 559 569 ext4_extent_t *ext = EXT4_EXTENT_FIRST(header); 570 571 // Release all extents and stop recursion 560 572 561 573 for (uint32_t i = 0; i < ext4_extent_header_get_entries_count(header); ++i, ++ext) { … … 568 580 } 569 581 582 // Release data block where the node was stored 583 570 584 rc = block_put(block); 571 585 if (rc != EOK) { … … 579 593 } 580 594 595 /** Release all data blocks starting from specified logical block. 596 * 597 * @param inode_ref i-node to release blocks from 598 * @param iblock_from first logical block to release 599 */ 581 600 int ext4_extent_release_blocks_from(ext4_inode_ref_t *inode_ref, 582 601 uint32_t iblock_from) … … 609 628 ext4_extent_get_start(path_ptr->extent); 610 629 630 // Release all blocks 611 631 rc = ext4_balloc_free_blocks(inode_ref, first_fblock, delete_count); 612 632 if (rc != EOK) { … … 614 634 } 615 635 636 // Correct counter 616 637 block_count -= delete_count; 617 638 ext4_extent_set_block_count(path_ptr->extent, block_count); 618 639 640 // Initialize the following loop 619 641 uint16_t entries = ext4_extent_header_get_entries_count(path_ptr->header); 620 642 ext4_extent_t *tmp_ext = path_ptr->extent + 1; … … 658 680 --path_ptr; 659 681 660 // release all successors in all levels661 while (path_ptr >= path) {682 // release all successors in all tree levels 683 while (path_ptr >= path) { 662 684 entries = ext4_extent_header_get_entries_count(path_ptr->header); 663 685 ext4_extent_index_t *index = path_ptr->index + 1; … … 665 687 EXT4_EXTENT_FIRST_INDEX(path_ptr->header) + entries; 666 688 689 // Correct entry because of changes in the previous iteration 667 690 if (check_tree) { 668 691 entries--; 669 692 ext4_extent_header_set_entries_count(path_ptr->header, entries); 670 } 671 693 } else { 694 // TODO check this condition 695 break; 696 } 697 698 // Iterate over all entries and release the whole subtrees 672 699 while (index < stop) { 673 700 rc = ext4_extent_release_branch(inode_ref, index); … … 682 709 path_ptr->block->dirty = true; 683 710 711 // Free the node if it is empty 684 712 if ((entries == 0) && (path_ptr != path)) { 685 713 rc = ext4_balloc_free_block(inode_ref, path_ptr->block->lba); … … 687 715 goto cleanup; 688 716 } 717 718 // Mark parent to be checked 689 719 check_tree = true; 690 720 } else { … … 711 741 } 712 742 743 /** TODO 744 * 745 */ 713 746 static int ext4_extent_append_extent(ext4_inode_ref_t *inode_ref, 714 747 ext4_extent_path_t *path, ext4_extent_path_t **last_path_item, -
uspace/lib/ext4/libext4_hash.c
r6773ff3 ree3b6150 227 227 } 228 228 229 230 /** Compute hash value of the string. 231 * 232 * @param hinfo hash info structure with information about 233 * the algorithm, hash seed and with the place 234 * for the output hash value 235 * @param len length of the name 236 * @param name name to be hashed 237 * @return error code 238 */ 229 239 int ext4_hash_string(ext4_hash_info_t *hinfo, int len, const char *name) 230 240 { -
uspace/lib/ext4/libext4_ialloc.c
r6773ff3 ree3b6150 40 40 #include "libext4.h" 41 41 42 43 /** Convert i-node number to relative index in block group. 44 * 45 * @param sb superblock 46 * @param inode i-node number to be converted 47 * @return index of the i-node in the block group 48 */ 42 49 static uint32_t ext4_ialloc_inode2index_in_group(ext4_superblock_t *sb, 43 50 uint32_t inode) … … 47 54 } 48 55 56 /** Convert relative index of i-node to absolute i-node number. 57 * 58 * @param sb superblock 59 * @param inode index to be converted 60 * @return absolute number of the i-node 61 */ 49 62 static uint32_t ext4_ialloc_index_in_group2inode(ext4_superblock_t *sb, 50 63 uint32_t index, uint32_t bgid) … … 54 67 } 55 68 69 /** Compute block group number from the i-node number. 70 * 71 * @param sb superblock 72 * @param inode i-node number to be found the block group for 73 * @return block group number computed from i-node number 74 */ 56 75 static uint32_t ext4_ialloc_get_bgid_of_inode(ext4_superblock_t *sb, 57 76 uint32_t inode) … … 63 82 64 83 84 /** Free i-node number and modify filesystem data structers. 85 * 86 * @param fs filesystem, where the i-node is located 87 * @param index index of i-node to be release 88 * @param is_dir flag us for information whether i-node is directory or not 89 */ 65 90 int ext4_ialloc_free_inode(ext4_filesystem_t *fs, uint32_t index, bool is_dir) 66 91 { … … 69 94 ext4_superblock_t *sb = fs->superblock; 70 95 96 // Compute index of block group and load it 71 97 uint32_t block_group = ext4_ialloc_get_bgid_of_inode(sb, index); 72 98 … … 77 103 } 78 104 105 // Load i-node bitmap 79 106 uint32_t bitmap_block_addr = ext4_block_group_get_inode_bitmap( 80 107 bg_ref->block_group, sb); … … 85 112 } 86 113 114 // Free i-node in the bitmap 87 115 uint32_t index_in_group = ext4_ialloc_inode2index_in_group(sb, index); 88 116 ext4_bitmap_free_bit(bitmap_block->data, index_in_group); 89 117 bitmap_block->dirty = true; 90 118 119 // Put back the block with bitmap 91 120 rc = block_put(bitmap_block); 92 121 if (rc != EOK) { … … 96 125 } 97 126 98 // if inode isdirectory, decrement used directories count127 // If released i-node is a directory, decrement used directories count 99 128 if (is_dir) { 100 129 uint32_t bg_used_dirs = ext4_block_group_get_used_dirs_count( … … 112 141 sb, free_inodes); 113 142 143 // Set unused i-nodes count if supported 114 144 if (ext4_block_group_has_flag(bg_ref->block_group, EXT4_BLOCK_GROUP_INODE_UNINIT)) { 115 145 uint32_t unused_inodes = ext4_block_group_get_itable_unused( … … 121 151 bg_ref->dirty = true; 122 152 153 // Put back the modified block group 123 154 rc = ext4_filesystem_put_block_group_ref(bg_ref); 124 155 if (rc != EOK) { … … 134 165 } 135 166 167 /** I-node allocation algorithm. 168 * 169 * This is more simple algorithm, than Orlov allocator used in the Linux kernel 170 * 171 * @param fs filesystem to allocate i-node on 172 * @param index output value - allocated i-node number 173 * @param is_dir flag if allocated i-node will be file or directory 174 * @return error code 175 */ 136 176 int ext4_ialloc_alloc_inode(ext4_filesystem_t *fs, uint32_t *index, bool is_dir) 137 177 { … … 145 185 uint32_t avg_free_inodes = sb_free_inodes / bg_count; 146 186 187 // Try to find free i-node in all block groups 147 188 while (bgid < bg_count) { 148 189 190 // Load block group to check 149 191 ext4_block_group_ref_t *bg_ref; 150 192 rc = ext4_filesystem_get_block_group_ref(fs, bgid, &bg_ref); … … 152 194 return rc; 153 195 } 196 154 197 ext4_block_group_t *bg = bg_ref->block_group; 155 198 199 // Read necessary values for algorithm 156 200 uint32_t free_blocks = ext4_block_group_get_free_blocks_count(bg, sb); 157 201 uint32_t free_inodes = ext4_block_group_get_free_inodes_count(bg, sb); 158 202 uint32_t used_dirs = ext4_block_group_get_used_dirs_count(bg, sb); 159 203 204 // Check if this block group is good candidate for allocation 160 205 if ((free_inodes >= avg_free_inodes) && (free_blocks > 0)) { 161 206 207 // Load block with bitmap 162 208 uint32_t bitmap_block_addr = ext4_block_group_get_inode_bitmap( 163 209 bg_ref->block_group, sb); … … 170 216 } 171 217 172 // Alloc bit218 // Try to allocate i-node in the bitmap 173 219 uint32_t inodes_in_group = ext4_superblock_get_inodes_in_group(sb, bgid); 174 220 uint32_t index_in_group; … … 176 222 bitmap_block->data, 0, &index_in_group, inodes_in_group); 177 223 178 // Block group is full (inodes)224 // Block group has not any free i-node 179 225 if (rc == ENOSPC) { 180 226 block_put(bitmap_block); … … 183 229 } 184 230 231 // Free i-node found, save the bitmap 185 232 bitmap_block->dirty = true; 186 233 … … 194 241 ext4_block_group_set_free_inodes_count(bg, sb, free_inodes); 195 242 243 // Decrement unused i-nodes counter if supported 196 244 if (ext4_block_group_has_flag(bg, EXT4_BLOCK_GROUP_INODE_UNINIT)) { 197 245 uint16_t unused_inodes = ext4_block_group_get_itable_unused(bg, sb); … … 200 248 } 201 249 250 // Increment used directories counter 202 251 if (is_dir) { 203 252 used_dirs++; … … 205 254 } 206 255 256 // Save modified block group 207 257 bg_ref->dirty = true; 208 258 … … 213 263 } 214 264 265 // Update superblock 215 266 sb_free_inodes--; 216 267 ext4_superblock_set_free_inodes_count(sb, sb_free_inodes); 217 268 269 // Compute the absolute i-nodex number 218 270 *index = ext4_ialloc_index_in_group2inode(sb, index_in_group, bgid); 219 271 … … 222 274 } 223 275 224 // Not modified276 // Block group not modified, put it and jump to the next block group 225 277 ext4_filesystem_put_block_group_ref(bg_ref); 226 278 ++bgid;
Note:
See TracChangeset
for help on using the changeset viewer.