Changeset d9bbe45 in mainline for uspace/lib/ext4/libext4_filesystem.c
- Timestamp:
- 2012-01-22T13:22:56Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- fcae007
- Parents:
- b7e0260
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/ext4/libext4_filesystem.c
rb7e0260 rd9bbe45 44 44 { 45 45 int rc; 46 ext4_superblock_t *temp_superblock;47 size_t block_size;48 uint32_t block_ids_per_block;49 int i;50 46 51 47 fs->device = service_id; … … 58 54 59 55 /* Read superblock from device */ 56 ext4_superblock_t *temp_superblock; 60 57 rc = ext4_superblock_read_direct(fs->device, &temp_superblock); 61 58 if (rc != EOK) { … … 65 62 66 63 /* Read block size from superblock and check */ 67 block_size = ext4_superblock_get_block_size(temp_superblock);64 uint32_t block_size = ext4_superblock_get_block_size(temp_superblock); 68 65 if (block_size > EXT4_MAX_BLOCK_SIZE) { 69 66 block_fini(fs->device); … … 78 75 } 79 76 80 block_ids_per_block = block_size / sizeof(uint32_t);77 uint32_t block_ids_per_block = block_size / sizeof(uint32_t); 81 78 fs->inode_block_limits[0] = EXT4_INODE_DIRECT_BLOCK_COUNT; 82 79 fs->inode_blocks_per_level[0] = 1; 83 for (i = 1; i < 4; i++) {80 for (int i = 1; i < 4; i++) { 84 81 fs->inode_blocks_per_level[i] = fs->inode_blocks_per_level[i-1] * 85 82 block_ids_per_block; … … 97 94 { 98 95 int rc = EOK; 96 99 97 if (write_sb) { 100 98 rc = ext4_superblock_write_direct(fs->device, fs->superblock); … … 149 147 { 150 148 int rc; 151 aoff64_t block_id; 152 uint32_t descriptors_per_block; 153 size_t offset; 154 ext4_block_group_ref_t *newref; 155 156 newref = malloc(sizeof(ext4_block_group_ref_t)); 149 150 ext4_block_group_ref_t *newref = malloc(sizeof(ext4_block_group_ref_t)); 157 151 if (newref == NULL) { 158 152 return ENOMEM; 159 153 } 160 154 161 descriptors_per_block = ext4_superblock_get_block_size(fs->superblock)155 uint32_t descriptors_per_block = ext4_superblock_get_block_size(fs->superblock) 162 156 / ext4_superblock_get_desc_size(fs->superblock); 163 157 164 158 /* Block group descriptor table starts at the next block after superblock */ 165 block_id = ext4_superblock_get_first_data_block(fs->superblock) + 1;159 aoff64_t block_id = ext4_superblock_get_first_data_block(fs->superblock) + 1; 166 160 167 161 /* Find the block containing the descriptor we are looking for */ 168 162 block_id += bgid / descriptors_per_block; 169 offset = (bgid % descriptors_per_block) * ext4_superblock_get_desc_size(fs->superblock);163 uint32_t offset = (bgid % descriptors_per_block) * ext4_superblock_get_desc_size(fs->superblock); 170 164 171 165 rc = block_get(&newref->block, fs->device, block_id, 0); … … 201 195 { 202 196 int rc; 203 aoff64_t block_id; 204 uint32_t block_group; 205 uint32_t offset_in_group; 206 uint32_t byte_offset_in_group; 207 size_t offset_in_block; 208 uint32_t inodes_per_group; 209 uint32_t inode_table_start; 210 uint16_t inode_size; 211 uint32_t block_size; 212 ext4_block_group_ref_t *bg_ref; 213 ext4_inode_ref_t *newref; 214 215 newref = malloc(sizeof(ext4_inode_ref_t)); 197 198 ext4_inode_ref_t *newref = malloc(sizeof(ext4_inode_ref_t)); 216 199 if (newref == NULL) { 217 200 return ENOMEM; 218 201 } 219 202 220 inodes_per_group = ext4_superblock_get_inodes_per_group(fs->superblock); 203 uint32_t inodes_per_group = 204 ext4_superblock_get_inodes_per_group(fs->superblock); 221 205 222 206 /* inode numbers are 1-based, but it is simpler to work with 0-based … … 224 208 */ 225 209 index -= 1; 226 block_group = index / inodes_per_group; 227 offset_in_group = index % inodes_per_group; 228 210 uint32_t block_group = index / inodes_per_group; 211 uint32_t offset_in_group = index % inodes_per_group; 212 213 ext4_block_group_ref_t *bg_ref; 229 214 rc = ext4_filesystem_get_block_group_ref(fs, block_group, &bg_ref); 230 215 if (rc != EOK) { … … 233 218 } 234 219 235 inode_table_start = ext4_block_group_get_inode_table_first_block(220 uint32_t inode_table_start = ext4_block_group_get_inode_table_first_block( 236 221 bg_ref->block_group, fs->superblock); 237 222 … … 242 227 } 243 228 244 inode_size = ext4_superblock_get_inode_size(fs->superblock); 245 block_size = ext4_superblock_get_block_size(fs->superblock); 246 247 byte_offset_in_group = offset_in_group * inode_size; 248 249 block_id = inode_table_start + (byte_offset_in_group / block_size); 250 offset_in_block = byte_offset_in_group % block_size; 251 229 uint16_t inode_size = ext4_superblock_get_inode_size(fs->superblock); 230 uint32_t block_size = ext4_superblock_get_block_size(fs->superblock); 231 uint32_t byte_offset_in_group = offset_in_group * inode_size; 232 233 aoff64_t block_id = inode_table_start + (byte_offset_in_group / block_size); 252 234 rc = block_get(&newref->block, fs->device, block_id, 0); 253 235 if (rc != EOK) { … … 256 238 } 257 239 240 uint32_t offset_in_block = byte_offset_in_group % block_size; 258 241 newref->inode = newref->block->data + offset_in_block; 259 242 /* we decremented index above, but need to store the original value … … 322 305 { 323 306 int rc; 307 324 308 // release all indirect blocks 325 309 326 uint32_t fblock;327 328 310 // 1) Single indirect 329 fblock = ext4_inode_get_indirect_block(inode_ref->inode, 0);311 uint32_t fblock = ext4_inode_get_indirect_block(inode_ref->inode, 0); 330 312 if (fblock != 0) { 331 313 rc = ext4_balloc_free_block(fs, inode_ref, fblock); … … 437 419 ext4_inode_ref_t *inode_ref, aoff64_t new_size) 438 420 { 439 aoff64_t old_size;440 aoff64_t size_diff;441 442 421 if (! ext4_inode_can_truncate(fs->superblock, inode_ref->inode)) { 443 422 // Unable to truncate … … 445 424 } 446 425 447 old_size = ext4_inode_get_size(fs->superblock, inode_ref->inode); 448 426 aoff64_t old_size = ext4_inode_get_size(fs->superblock, inode_ref->inode); 449 427 if (old_size == new_size) { 450 428 // Nothing to do 451 429 return EOK; 452 430 } 453 454 uint32_t block_size;455 uint32_t blocks_count, total_blocks;456 uint32_t i;457 458 block_size = ext4_superblock_get_block_size(fs->superblock);459 431 460 432 if (old_size < new_size) { … … 465 437 } 466 438 467 size_diff = old_size - new_size; 468 blocks_count = size_diff / block_size; 439 aoff64_t size_diff = old_size - new_size; 440 uint32_t block_size = ext4_superblock_get_block_size(fs->superblock); 441 uint32_t blocks_count = size_diff / block_size; 469 442 if (size_diff % block_size != 0) { 470 443 blocks_count++; 471 444 } 472 445 473 total_blocks = old_size / block_size;446 uint32_t total_blocks = old_size / block_size; 474 447 if (old_size % block_size != 0) { 475 448 total_blocks++; … … 477 450 478 451 // starting from 1 because of logical blocks are numbered from 0 479 for ( i = 1; i <= blocks_count; ++i) {452 for (uint32_t i = 1; i <= blocks_count; ++i) { 480 453 // TODO check retval 481 454 ext4_filesystem_release_inode_block(fs, inode_ref, total_blocks - i); … … 493 466 { 494 467 int rc; 495 uint32_t offset_in_block; 468 469 496 470 uint32_t current_block; 497 aoff64_t block_offset_in_level;498 int i;499 int level;500 block_t *block;501 471 502 472 /* Handle inode using extents */ … … 517 487 518 488 /* Determine the indirection level needed to get the desired block */ 519 level = -1;520 for (i = 1; i < 4; i++) {489 int level = -1; 490 for (int i = 1; i < 4; i++) { 521 491 if (iblock < fs->inode_block_limits[i]) { 522 492 level = i; … … 530 500 531 501 /* Compute offsets for the topmost level */ 532 block_offset_in_level = iblock - fs->inode_block_limits[level-1];502 aoff64_t block_offset_in_level = iblock - fs->inode_block_limits[level-1]; 533 503 current_block = ext4_inode_get_indirect_block(inode, level-1); 534 offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1];504 uint32_t offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1]; 535 505 536 506 if (current_block == 0) { … … 538 508 return EOK; 539 509 } 510 511 block_t *block; 540 512 541 513 /* Navigate through other levels, until we find the block number … … 584 556 ext4_inode_ref_t *inode_ref, aoff64_t iblock, uint32_t fblock) 585 557 { 586 587 int rc; 588 uint32_t offset_in_block; 589 uint32_t current_block, new_block_addr; 590 uint32_t block_size; 591 aoff64_t block_offset_in_level; 592 int i; 593 int level; 594 block_t *block, *new_block; 558 int rc; 559 595 560 596 561 /* Handle inode using extents */ … … 609 574 610 575 /* Determine the indirection level needed to get the desired block */ 611 level = -1;612 for (i = 1; i < 4; i++) {576 int level = -1; 577 for (int i = 1; i < 4; i++) { 613 578 if (iblock < fs->inode_block_limits[i]) { 614 579 level = i; … … 621 586 } 622 587 623 block_size = ext4_superblock_get_block_size(fs->superblock); 588 589 590 uint32_t block_size = ext4_superblock_get_block_size(fs->superblock); 624 591 625 592 /* Compute offsets for the topmost level */ 626 block_offset_in_level = iblock - fs->inode_block_limits[level-1]; 627 current_block = ext4_inode_get_indirect_block(inode_ref->inode, level-1); 628 offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1]; 593 aoff64_t block_offset_in_level = iblock - fs->inode_block_limits[level-1]; 594 uint32_t current_block = ext4_inode_get_indirect_block(inode_ref->inode, level-1); 595 uint32_t offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1]; 596 597 uint32_t new_block_addr; 598 block_t *block, *new_block; 629 599 630 600 if (current_block == 0) { … … 634 604 EXT4FS_DBG("error in allocation"); 635 605 } 636 // EXT4FS_DBG("AAA: new addr \%u, level = \%u", new_block_addr, level);637 606 638 607 ext4_inode_set_indirect_block(inode_ref->inode, level - 1, new_block_addr); … … 677 646 EXT4FS_DBG("allocation error"); 678 647 } 679 // EXT4FS_DBG("BBB: new addr \%u, offset = \%u, level = \%u", new_block_addr, offset_in_block, level);680 648 681 649 rc = block_get(&new_block, fs->device, new_block_addr, BLOCK_FLAGS_NOREAD); … … 730 698 { 731 699 int rc; 700 701 702 /* TODO handle extents */ 703 704 732 705 uint32_t fblock; 733 int i;734 int level;735 aoff64_t block_offset_in_level;736 uint32_t current_block;737 uint32_t offset_in_block;738 block_t *block;739 706 ext4_inode_t *inode = inode_ref->inode; 740 741 /* TODO handle extents */742 743 707 744 708 /* Handle simple case when we are dealing with direct reference */ … … 756 720 757 721 /* Determine the indirection level needed to get the desired block */ 758 level = -1;759 for (i = 1; i < 4; i++) {722 int level = -1; 723 for (int i = 1; i < 4; i++) { 760 724 if (iblock < fs->inode_block_limits[i]) { 761 725 level = i; … … 769 733 770 734 /* Compute offsets for the topmost level */ 771 block_offset_in_level = iblock - fs->inode_block_limits[level-1];772 current_block = ext4_inode_get_indirect_block(inode, level-1);773 offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1];735 aoff64_t block_offset_in_level = iblock - fs->inode_block_limits[level-1]; 736 uint32_t current_block = ext4_inode_get_indirect_block(inode, level-1); 737 uint32_t offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1]; 774 738 775 739 /* Navigate through other levels, until we find the block number 776 740 * or find null reference meaning we are dealing with sparse file 777 741 */ 742 block_t *block; 778 743 while (level > 0) { 779 744 rc = block_get(&block, fs->device, current_block, 0);
Note:
See TracChangeset
for help on using the changeset viewer.