Changeset 06d85e5 in mainline for uspace/lib/ext4/libext4_filesystem.c
- Timestamp:
- 2012-06-18T11:09:34Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2616a75b
- Parents:
- 9a487cc
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/ext4/libext4_filesystem.c
r9a487cc r06d85e5 53 53 fs->device = service_id; 54 54 55 / / Initialize block library (4096 is size of communication channel)55 /* Initialize block library (4096 is size of communication channel) */ 56 56 rc = block_init(EXCHANGE_SERIALIZE, fs->device, 4096); 57 57 if (rc != EOK) { … … 60 60 } 61 61 62 / / Read superblock from device to memory62 /* Read superblock from device to memory */ 63 63 ext4_superblock_t *temp_superblock; 64 64 rc = ext4_superblock_read_direct(fs->device, &temp_superblock); … … 69 69 } 70 70 71 / / Read block size from superblock and check71 /* Read block size from superblock and check */ 72 72 uint32_t block_size = ext4_superblock_get_block_size(temp_superblock); 73 73 if (block_size > EXT4_MAX_BLOCK_SIZE) { … … 77 77 } 78 78 79 / / Initialize block caching by libblock79 /* Initialize block caching by libblock */ 80 80 rc = block_cache_init(service_id, block_size, 0, CACHE_MODE_WT); 81 81 if (rc != EOK) { … … 85 85 } 86 86 87 / / Compute limits for indirect block levels87 /* Compute limits for indirect block levels */ 88 88 uint32_t block_ids_per_block = block_size / sizeof(uint32_t); 89 89 fs->inode_block_limits[0] = EXT4_INODE_DIRECT_BLOCK_COUNT; … … 96 96 } 97 97 98 / / Return loaded superblock98 /* Return loaded superblock */ 99 99 fs->superblock = temp_superblock; 100 100 … … 108 108 } 109 109 110 / / Mark system as mounted110 /* Mark system as mounted */ 111 111 ext4_superblock_set_state(fs->superblock, EXT4_SUPERBLOCK_STATE_ERROR_FS); 112 112 rc = ext4_superblock_write_direct(fs->device, fs->superblock); … … 131 131 int rc = EOK; 132 132 133 / / Write the superblock to the device133 /* Write the superblock to the device */ 134 134 ext4_superblock_set_state(fs->superblock, EXT4_SUPERBLOCK_STATE_VALID_FS); 135 135 rc = ext4_superblock_write_direct(fs->device, fs->superblock); 136 136 137 / / Release memory space for superblock137 /* Release memory space for superblock */ 138 138 free(fs->superblock); 139 139 140 / / Finish work with block library140 /* Finish work with block library */ 141 141 block_fini(fs->device); 142 142 … … 155 155 int rc; 156 156 157 / / Check superblock157 /* Check superblock */ 158 158 rc = ext4_superblock_check_sanity(fs->superblock); 159 159 if (rc != EOK) { … … 176 176 int ext4_filesystem_check_features(ext4_filesystem_t *fs, bool *read_only) 177 177 { 178 / / Feature flags are present only in higher revisions178 /* Feature flags are present only in higher revisions */ 179 179 if (ext4_superblock_get_rev_level(fs->superblock) == 0) { 180 180 *read_only = false; … … 182 182 } 183 183 184 // Check incompatible features - if filesystem has some, 185 // volume can't be mounted 184 /* Check incompatible features - if filesystem has some, 185 * volume can't be mounted 186 */ 186 187 uint32_t incompatible_features; 187 188 incompatible_features = ext4_superblock_get_features_incompatible(fs->superblock); … … 191 192 } 192 193 193 // Check read-only features, if filesystem has some, 194 // volume can be mount only in read-only mode 194 /* Check read-only features, if filesystem has some, 195 * volume can be mount only in read-only mode 196 */ 195 197 uint32_t compatible_read_only; 196 198 compatible_read_only = ext4_superblock_get_features_read_only(fs->superblock); … … 216 218 int rc; 217 219 218 / / Allocate memory for new structure220 /* Allocate memory for new structure */ 219 221 ext4_block_group_ref_t *newref = malloc(sizeof(ext4_block_group_ref_t)); 220 222 if (newref == NULL) { … … 222 224 } 223 225 224 / / Compute number of descriptors, that fits in one data block226 /* Compute number of descriptors, that fits in one data block */ 225 227 uint32_t descriptors_per_block = ext4_superblock_get_block_size(fs->superblock) 226 228 / ext4_superblock_get_desc_size(fs->superblock); 227 229 228 / / Block group descriptor table starts at the next block after superblock230 /* Block group descriptor table starts at the next block after superblock */ 229 231 aoff64_t block_id = ext4_superblock_get_first_data_block(fs->superblock) + 1; 230 232 231 / / Find the block containing the descriptor we are looking for233 /* Find the block containing the descriptor we are looking for */ 232 234 block_id += bgid / descriptors_per_block; 233 235 uint32_t offset = (bgid % descriptors_per_block) * ext4_superblock_get_desc_size(fs->superblock); 234 236 235 / / Load block with descriptors237 /* Load block with descriptors */ 236 238 rc = block_get(&newref->block, fs->device, block_id, 0); 237 239 if (rc != EOK) { … … 240 242 } 241 243 242 / / Inititialize in-memory representation244 /* Inititialize in-memory representation */ 243 245 newref->block_group = newref->block->data + offset; 244 246 newref->fs = fs; … … 263 265 ext4_block_group_t *bg) 264 266 { 265 / / If checksum not supported, 0 will be returned267 /* If checksum not supported, 0 will be returned */ 266 268 uint16_t crc = 0; 267 269 268 / / Compute the checksum only if the filesystem supports it270 /* Compute the checksum only if the filesystem supports it */ 269 271 if (ext4_superblock_has_feature_read_only(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) { 270 272 … … 274 276 uint32_t offset = (uint32_t)(checksum - base); 275 277 276 / / Convert block group index to little endian278 /* Convert block group index to little endian */ 277 279 uint32_t le_group = host2uint32_t_le(bgid); 278 280 279 / / Initialization281 /* Initialization */ 280 282 crc = crc16(~0, sb->uuid, sizeof(sb->uuid)); 281 283 282 / / Include index of block group284 /* Include index of block group */ 283 285 crc = crc16(crc, (uint8_t *)&le_group, sizeof(le_group)); 284 286 285 / / Compute crc from the first part (stop before checksum field)287 /* Compute crc from the first part (stop before checksum field) */ 286 288 crc = crc16(crc, (uint8_t *)bg, offset); 287 289 288 / / Skip checksum290 /* Skip checksum */ 289 291 offset += sizeof(bg->checksum); 290 292 291 / / Checksum of the rest of block group descriptor293 /* Checksum of the rest of block group descriptor */ 292 294 if ((ext4_superblock_has_feature_incompatible(sb, EXT4_FEATURE_INCOMPAT_64BIT)) && 293 295 offset < ext4_superblock_get_desc_size(sb)) { … … 310 312 int rc; 311 313 312 / / Check if reference modified314 /* Check if reference modified */ 313 315 if (ref->dirty) { 314 316 315 / / Compute new checksum of block group317 /* Compute new checksum of block group */ 316 318 uint16_t checksum = ext4_filesystem_bg_checksum( 317 319 ref->fs->superblock, ref->index, ref->block_group); 318 320 ext4_block_group_set_checksum(ref->block_group, checksum); 319 321 320 / / Mark block dirty for writing changes to physical device322 /* Mark block dirty for writing changes to physical device */ 321 323 ref->block->dirty = true; 322 324 } 323 325 324 / / Put back block, that contains block group descriptor326 /* Put back block, that contains block group descriptor */ 325 327 rc = block_put(ref->block); 326 328 free(ref); … … 341 343 int rc; 342 344 343 / / Allocate memory for new structure345 /* Allocate memory for new structure */ 344 346 ext4_inode_ref_t *newref = malloc(sizeof(ext4_inode_ref_t)); 345 347 if (newref == NULL) { … … 347 349 } 348 350 349 / / Compute number of i-nodes, that fits in one data block351 /* Compute number of i-nodes, that fits in one data block */ 350 352 uint32_t inodes_per_group = 351 353 ext4_superblock_get_inodes_per_group(fs->superblock); 352 354 353 /* 354 * inode numbers are 1-based, but it is simpler to work with 0-based 355 /* Inode numbers are 1-based, but it is simpler to work with 0-based 355 356 * when computing indices 356 357 */ … … 359 360 uint32_t offset_in_group = index % inodes_per_group; 360 361 361 / / Load block group, where i-node is located362 /* Load block group, where i-node is located */ 362 363 ext4_block_group_ref_t *bg_ref; 363 364 rc = ext4_filesystem_get_block_group_ref(fs, block_group, &bg_ref); … … 367 368 } 368 369 369 / / Load block address, where i-node table is located370 /* Load block address, where i-node table is located */ 370 371 uint32_t inode_table_start = ext4_block_group_get_inode_table_first_block( 371 372 bg_ref->block_group, fs->superblock); 372 373 373 / / Put back block group reference (not needed more)374 /* Put back block group reference (not needed more) */ 374 375 rc = ext4_filesystem_put_block_group_ref(bg_ref); 375 376 if (rc != EOK) { … … 378 379 } 379 380 380 / / Compute position of i-node in the block group381 /* Compute position of i-node in the block group */ 381 382 uint16_t inode_size = ext4_superblock_get_inode_size(fs->superblock); 382 383 uint32_t block_size = ext4_superblock_get_block_size(fs->superblock); 383 384 uint32_t byte_offset_in_group = offset_in_group * inode_size; 384 385 385 / / Compute block address386 /* Compute block address */ 386 387 aoff64_t block_id = inode_table_start + (byte_offset_in_group / block_size); 387 388 rc = block_get(&newref->block, fs->device, block_id, 0); … … 391 392 } 392 393 393 / / Compute position of i-node in the data block394 /* Compute position of i-node in the data block */ 394 395 uint32_t offset_in_block = byte_offset_in_group % block_size; 395 396 newref->inode = newref->block->data + offset_in_block; 396 397 397 / / We need to store the original value of index in the reference398 /* We need to store the original value of index in the reference */ 398 399 newref->index = index + 1; 399 400 newref->fs = fs; … … 414 415 int rc; 415 416 416 / / Check if reference modified417 /* Check if reference modified */ 417 418 if (ref->dirty) { 418 419 419 / / Mark block dirty for writing changes to physical device420 /* Mark block dirty for writing changes to physical device */ 420 421 ref->block->dirty = true; 421 422 } 422 423 423 / / Put back block, that contains i-node424 /* Put back block, that contains i-node */ 424 425 rc = block_put(ref->block); 425 426 free(ref); … … 440 441 int rc; 441 442 442 / / Check if newly allocated i-node will be a directory443 /* Check if newly allocated i-node will be a directory */ 443 444 bool is_dir = false; 444 445 if (flags & L_DIRECTORY) { … … 446 447 } 447 448 448 / / Allocate inode by allocation algorithm449 /* Allocate inode by allocation algorithm */ 449 450 uint32_t index; 450 451 rc = ext4_ialloc_alloc_inode(fs, &index, is_dir); … … 453 454 } 454 455 455 / / Load i-node from on-disk i-node table456 /* Load i-node from on-disk i-node table */ 456 457 rc = ext4_filesystem_get_inode_ref(fs, index, inode_ref); 457 458 if (rc != EOK) { … … 460 461 } 461 462 462 / / Initialize i-node463 /* Initialize i-node */ 463 464 ext4_inode_t *inode = (*inode_ref)->inode; 464 465 465 466 if (is_dir) { 466 467 ext4_inode_set_mode(fs->superblock, inode, EXT4_INODE_MODE_DIRECTORY); 467 ext4_inode_set_links_count(inode, 1); / / '.' entry468 ext4_inode_set_links_count(inode, 1); /* '.' entry */ 468 469 } else { 469 470 ext4_inode_set_mode(fs->superblock, inode, EXT4_INODE_MODE_FILE); … … 482 483 ext4_inode_set_generation(inode, 0); 483 484 484 / / Reset blocks array485 /* Reset blocks array */ 485 486 for (uint32_t i = 0; i < EXT4_INODE_BLOCKS; i++) { 486 487 inode->blocks[i] = 0; 487 488 } 488 489 489 / / Initialize extents if needed490 /* Initialize extents if needed */ 490 491 if (ext4_superblock_has_feature_incompatible( 491 492 fs->superblock, EXT4_FEATURE_INCOMPAT_EXTENTS)) { … … 493 494 ext4_inode_set_flag(inode, EXT4_INODE_FLAG_EXTENTS); 494 495 495 / / Initialize extent root header496 /* Initialize extent root header */ 496 497 ext4_extent_header_t *header = ext4_inode_get_extent_header(inode); 497 498 ext4_extent_header_set_depth(header, 0); … … 522 523 ext4_filesystem_t *fs = inode_ref->fs; 523 524 524 / / For extents must be data block destroyed by other way525 /* For extents must be data block destroyed by other way */ 525 526 if (ext4_superblock_has_feature_incompatible( 526 527 fs->superblock, EXT4_FEATURE_INCOMPAT_EXTENTS) && 527 528 ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS)) { 528 529 529 / / Data structures are released during truncate operation...530 /* Data structures are released during truncate operation... */ 530 531 goto finish; 531 532 } 532 533 533 / / Release all indirect (no data) blocks534 535 / / 1) Single indirect534 /* Release all indirect (no data) blocks */ 535 536 /* 1) Single indirect */ 536 537 uint32_t fblock = ext4_inode_get_indirect_block(inode_ref->inode, 0); 537 538 if (fblock != 0) { … … 548 549 uint32_t count = block_size / sizeof(uint32_t); 549 550 550 / / 2) Double indirect551 /* 2) Double indirect */ 551 552 fblock = ext4_inode_get_indirect_block(inode_ref->inode, 1); 552 553 if (fblock != 0) { … … 579 580 580 581 581 / / 3) Tripple indirect582 /* 3) Tripple indirect */ 582 583 block_t *subblock; 583 584 fblock = ext4_inode_get_indirect_block(inode_ref->inode, 2); … … 637 638 finish: 638 639 639 / / Mark inode dirty for writing to the physical device640 /* Mark inode dirty for writing to the physical device */ 640 641 inode_ref->dirty = true; 641 642 642 / / Free inode by allocator643 /* Free inode by allocator */ 643 644 if (ext4_inode_is_type(fs->superblock, inode_ref->inode, 644 645 EXT4_INODE_MODE_DIRECTORY)) { … … 667 668 ext4_superblock_t *sb = inode_ref->fs->superblock; 668 669 669 / / Check flags, if i-node can be truncated670 /* Check flags, if i-node can be truncated */ 670 671 if (! ext4_inode_can_truncate(sb, inode_ref->inode)) { 671 672 return EINVAL; 672 673 } 673 674 674 / / If sizes are equal, nothing has to be done.675 /* If sizes are equal, nothing has to be done. */ 675 676 aoff64_t old_size = ext4_inode_get_size(sb, inode_ref->inode); 676 677 if (old_size == new_size) { … … 678 679 } 679 680 680 / / It's not suppported to make the larger file by truncate operation681 /* It's not suppported to make the larger file by truncate operation */ 681 682 if (old_size < new_size) { 682 683 return EINVAL; 683 684 } 684 685 685 / / Compute how many blocks will be released686 /* Compute how many blocks will be released */ 686 687 aoff64_t size_diff = old_size - new_size; 687 688 uint32_t block_size = ext4_superblock_get_block_size(sb); … … 700 701 ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS)) { 701 702 702 / / Extents require special operation703 /* Extents require special operation */ 703 704 704 705 rc = ext4_extent_release_blocks_from(inode_ref, … … 709 710 } else { 710 711 711 / / Release data blocks from the end of file712 713 / / Starting from 1 because of logical blocks are numbered from 0712 /* Release data blocks from the end of file */ 713 714 /* Starting from 1 because of logical blocks are numbered from 0 */ 714 715 for (uint32_t i = 1; i <= diff_blocks_count; ++i) { 715 716 rc = ext4_filesystem_release_inode_block(inode_ref, old_blocks_count - i); … … 720 721 } 721 722 722 / / Update i-node723 /* Update i-node */ 723 724 ext4_inode_set_size(inode_ref->inode, new_size); 724 725 inode_ref->dirty = true; … … 741 742 ext4_filesystem_t *fs = inode_ref->fs; 742 743 743 / / For empty file is situation simple744 /* For empty file is situation simple */ 744 745 if (ext4_inode_get_size(fs->superblock, inode_ref->inode) == 0) { 745 746 *fblock = 0; … … 749 750 uint32_t current_block; 750 751 751 / / Handle i-node using extents752 /* Handle i-node using extents */ 752 753 if (ext4_superblock_has_feature_incompatible(fs->superblock, EXT4_FEATURE_INCOMPAT_EXTENTS) && 753 754 ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS)) { … … 766 767 ext4_inode_t *inode = inode_ref->inode; 767 768 768 / / Direct block are read directly from array in i-node structure769 /* Direct block are read directly from array in i-node structure */ 769 770 if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) { 770 771 current_block = ext4_inode_get_direct_block(inode, (uint32_t)iblock); … … 773 774 } 774 775 775 / / Determine indirection level of the target block776 /* Determine indirection level of the target block */ 776 777 int level = -1; 777 778 for (int i = 1; i < 4; i++) { … … 786 787 } 787 788 788 / / Compute offsets for the topmost level789 /* Compute offsets for the topmost level */ 789 790 aoff64_t block_offset_in_level = iblock - fs->inode_block_limits[level-1]; 790 791 current_block = ext4_inode_get_indirect_block(inode, level-1); 791 792 uint32_t offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1]; 792 793 793 / / Sparse file794 /* Sparse file */ 794 795 if (current_block == 0) { 795 796 *fblock = 0; … … 804 805 while (level > 0) { 805 806 806 / / Load indirect block807 /* Load indirect block */ 807 808 rc = block_get(&block, fs->device, current_block, 0); 808 809 if (rc != EOK) { … … 810 811 } 811 812 812 / / Read block address from indirect block813 /* Read block address from indirect block */ 813 814 current_block = uint32_t_le2host(((uint32_t*)block->data)[offset_in_block]); 814 815 815 / / Put back indirect block untouched816 /* Put back indirect block untouched */ 816 817 rc = block_put(block); 817 818 if (rc != EOK) { … … 819 820 } 820 821 821 / / Check for sparse file822 /* Check for sparse file */ 822 823 if (current_block == 0) { 823 824 *fblock = 0; … … 825 826 } 826 827 827 / / Jump to the next level828 /* Jump to the next level */ 828 829 level -= 1; 829 830 830 / / Termination condition - we have address of data block loaded831 /* Termination condition - we have address of data block loaded */ 831 832 if (level == 0) { 832 833 break; 833 834 } 834 835 835 / / Visit the next level836 /* Visit the next level */ 836 837 block_offset_in_level %= fs->inode_blocks_per_level[level]; 837 838 offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1]; … … 857 858 ext4_filesystem_t *fs = inode_ref->fs; 858 859 859 / / Handle inode using extents860 /* Handle inode using extents */ 860 861 if (ext4_superblock_has_feature_compatible(fs->superblock, EXT4_FEATURE_INCOMPAT_EXTENTS) && 861 862 ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS)) { 862 / / not reachable !!!863 /* not reachable !!! */ 863 864 return ENOTSUP; 864 865 } 865 866 866 / / Handle simple case when we are dealing with direct reference867 /* Handle simple case when we are dealing with direct reference */ 867 868 if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) { 868 869 ext4_inode_set_direct_block(inode_ref->inode, (uint32_t)iblock, fblock); … … 871 872 } 872 873 873 / / Determine the indirection level needed to get the desired block874 /* Determine the indirection level needed to get the desired block */ 874 875 int level = -1; 875 876 for (int i = 1; i < 4; i++) { … … 886 887 uint32_t block_size = ext4_superblock_get_block_size(fs->superblock); 887 888 888 / / Compute offsets for the topmost level889 /* Compute offsets for the topmost level */ 889 890 aoff64_t block_offset_in_level = iblock - fs->inode_block_limits[level-1]; 890 891 uint32_t current_block = ext4_inode_get_indirect_block(inode_ref->inode, level-1); … … 894 895 block_t *block, *new_block; 895 896 896 / / Is needed to allocate indirect block on the i-node level897 /* Is needed to allocate indirect block on the i-node level */ 897 898 if (current_block == 0) { 898 899 899 / / Allocate new indirect block900 /* Allocate new indirect block */ 900 901 rc = ext4_balloc_alloc_block(inode_ref, &new_block_addr); 901 902 if (rc != EOK) { … … 903 904 } 904 905 905 / / Update i-node906 /* Update i-node */ 906 907 ext4_inode_set_indirect_block(inode_ref->inode, level - 1, new_block_addr); 907 908 inode_ref->dirty = true; 908 909 909 / / Load newly allocated block910 /* Load newly allocated block */ 910 911 rc = block_get(&new_block, fs->device, new_block_addr, BLOCK_FLAGS_NOREAD); 911 912 if (rc != EOK) { … … 914 915 } 915 916 916 / / Initialize new block917 /* Initialize new block */ 917 918 memset(new_block->data, 0, block_size); 918 919 new_block->dirty = true; 919 920 920 / / Put back the allocated block921 /* Put back the allocated block */ 921 922 rc = block_put(new_block); 922 923 if (rc != EOK) { … … 941 942 if ((level > 1) && (current_block == 0)) { 942 943 943 / / Allocate new block944 /* Allocate new block */ 944 945 rc = ext4_balloc_alloc_block(inode_ref, &new_block_addr); 945 946 if (rc != EOK) { … … 948 949 } 949 950 950 / / Load newly allocated block951 /* Load newly allocated block */ 951 952 rc = block_get(&new_block, fs->device, new_block_addr, BLOCK_FLAGS_NOREAD); 952 953 if (rc != EOK) { … … 955 956 } 956 957 957 / / Initialize allocated block958 /* Initialize allocated block */ 958 959 memset(new_block->data, 0, block_size); 959 960 new_block->dirty = true; … … 965 966 } 966 967 967 / / Write block address to the parent968 /* Write block address to the parent */ 968 969 ((uint32_t*)block->data)[offset_in_block] = host2uint32_t_le(new_block_addr); 969 970 block->dirty = true; … … 971 972 } 972 973 973 / / Will be finished, write the fblock address974 /* Will be finished, write the fblock address */ 974 975 if (level == 1) { 975 976 ((uint32_t*)block->data)[offset_in_block] = host2uint32_t_le(fblock); … … 1014 1015 ext4_filesystem_t *fs = inode_ref->fs; 1015 1016 1016 / / EXTENTS are handled otherwise = there is not support in this function1017 /* EXTENTS are handled otherwise = there is not support in this function */ 1017 1018 assert(! (ext4_superblock_has_feature_incompatible(fs->superblock, 1018 1019 EXT4_FEATURE_INCOMPAT_EXTENTS) && … … 1021 1022 ext4_inode_t *inode = inode_ref->inode; 1022 1023 1023 / / Handle simple case when we are dealing with direct reference1024 /* Handle simple case when we are dealing with direct reference */ 1024 1025 if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) { 1025 1026 fblock = ext4_inode_get_direct_block(inode, iblock); 1026 / / Sparse file1027 /* Sparse file */ 1027 1028 if (fblock == 0) { 1028 1029 return EOK; … … 1034 1035 1035 1036 1036 / / Determine the indirection level needed to get the desired block1037 /* Determine the indirection level needed to get the desired block */ 1037 1038 int level = -1; 1038 1039 for (int i = 1; i < 4; i++) { … … 1047 1048 } 1048 1049 1049 / / Compute offsets for the topmost level1050 /* Compute offsets for the topmost level */ 1050 1051 aoff64_t block_offset_in_level = iblock - fs->inode_block_limits[level-1]; 1051 1052 uint32_t current_block = ext4_inode_get_indirect_block(inode, level-1); … … 1064 1065 current_block = uint32_t_le2host(((uint32_t*)block->data)[offset_in_block]); 1065 1066 1066 / / Set zero if physical data block address found1067 /* Set zero if physical data block address found */ 1067 1068 if (level == 1) { 1068 1069 ((uint32_t*)block->data)[offset_in_block] = host2uint32_t_le(0); … … 1095 1096 } 1096 1097 1097 / / Physical block is not referenced, it can be released1098 /* Physical block is not referenced, it can be released */ 1098 1099 1099 1100 return ext4_balloc_free_block(inode_ref, fblock); … … 1113 1114 int rc; 1114 1115 1115 / / Handle extents separately1116 /* Handle extents separately */ 1116 1117 if (ext4_superblock_has_feature_incompatible( 1117 1118 inode_ref->fs->superblock, EXT4_FEATURE_INCOMPAT_EXTENTS) && … … 1124 1125 ext4_superblock_t *sb = inode_ref->fs->superblock; 1125 1126 1126 / / Compute next block index and allocate data block1127 /* Compute next block index and allocate data block */ 1127 1128 uint64_t inode_size = ext4_inode_get_size(sb, inode_ref->inode); 1128 1129 uint32_t block_size = ext4_superblock_get_block_size(sb); 1129 1130 1130 / / Align size i-node size1131 /* Align size i-node size */ 1131 1132 if ((inode_size % block_size) != 0) { 1132 1133 inode_size += block_size - (inode_size % block_size); 1133 1134 } 1134 1135 1135 / / Logical blocks are numbered from 01136 /* Logical blocks are numbered from 0 */ 1136 1137 uint32_t new_block_idx = inode_size / block_size; 1137 1138 1138 / / Allocate new physical block1139 /* Allocate new physical block */ 1139 1140 uint32_t phys_block; 1140 1141 rc = ext4_balloc_alloc_block(inode_ref, &phys_block); … … 1143 1144 } 1144 1145 1145 / / Add physical block address to the i-node1146 /* Add physical block address to the i-node */ 1146 1147 rc = ext4_filesystem_set_inode_data_block_index(inode_ref, new_block_idx, phys_block); 1147 1148 if (rc != EOK) { … … 1150 1151 } 1151 1152 1152 / / Update i-node1153 /* Update i-node */ 1153 1154 ext4_inode_set_size(inode_ref->inode, inode_size + block_size); 1154 1155 inode_ref->dirty = true; … … 1173 1174 inode_ref->fs->superblock); 1174 1175 1175 / / Deletion time is used for holding next item of the list1176 /* Deletion time is used for holding next item of the list */ 1176 1177 ext4_inode_set_deletion_time(inode_ref->inode, next_orphan); 1177 1178 1178 / / Head of the list is in the superblock1179 /* Head of the list is in the superblock */ 1179 1180 ext4_superblock_set_last_orphan( 1180 1181 inode_ref->fs->superblock, inode_ref->index); … … 1196 1197 int rc; 1197 1198 1198 / / Get head of the linked list1199 /* Get head of the linked list */ 1199 1200 uint32_t last_orphan = ext4_superblock_get_last_orphan( 1200 1201 inode_ref->fs->superblock); … … 1210 1211 uint32_t next_orphan = ext4_inode_get_deletion_time(current->inode); 1211 1212 1212 / / Check if the head is the target1213 /* Check if the head is the target */ 1213 1214 if (last_orphan == inode_ref->index) { 1214 1215 ext4_superblock_set_last_orphan(inode_ref->fs->superblock, next_orphan); 1215 // ext4_inode_set_deletion_time(inode_ref->inode, 0);1216 // inode_ref->dirty = true;1217 1216 return EOK; 1218 1217 } … … 1220 1219 bool found = false; 1221 1220 1222 / / Walk thourgh the linked list1221 /* Walk thourgh the linked list */ 1223 1222 while (next_orphan != 0) { 1224 1223 1225 / / Found?1224 /* Found? */ 1226 1225 if (next_orphan == inode_ref->index) { 1227 1226 next_orphan = ext4_inode_get_deletion_time(inode_ref->inode); 1228 1227 ext4_inode_set_deletion_time(current->inode, next_orphan); 1229 // ext4_inode_set_deletion_time(inode_ref->inode, 0);1230 // inode_ref->dirty = true;1231 1228 current->dirty = true; 1232 1229 found = true;
Note:
See TracChangeset
for help on using the changeset viewer.