Changeset a35b458 in mainline for uspace/lib/ext4/src/directory_index.c
- Timestamp:
- 2018-03-02T20:10:49Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f1380b7
- Parents:
- 3061bc1
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:38:31)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:10:49)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/ext4/src/directory_index.c
r3061bc1 ra35b458 244 244 if (rc != EOK) 245 245 return rc; 246 246 247 247 block_t *block; 248 248 rc = block_get(&block, dir->fs->device, fblock, BLOCK_FLAGS_NONE); 249 249 if (rc != EOK) 250 250 return rc; 251 251 252 252 /* Initialize pointers to data structures */ 253 253 ext4_directory_dx_root_t *root = block->data; 254 254 ext4_directory_dx_root_info_t *info = &(root->info); 255 255 256 256 /* Initialize root info structure */ 257 257 uint8_t hash_version = 258 258 ext4_superblock_get_default_hash_version(dir->fs->superblock); 259 259 260 260 ext4_directory_dx_root_info_set_hash_version(info, hash_version); 261 261 ext4_directory_dx_root_info_set_indirect_levels(info, 0); 262 262 ext4_directory_dx_root_info_set_info_length(info, 8); 263 263 264 264 /* Set limit and current number of entries */ 265 265 ext4_directory_dx_countlimit_t *countlimit = 266 266 (ext4_directory_dx_countlimit_t *) &root->entries; 267 267 ext4_directory_dx_countlimit_set_count(countlimit, 1); 268 268 269 269 uint32_t block_size = 270 270 ext4_superblock_get_block_size(dir->fs->superblock); … … 274 274 uint16_t root_limit = entry_space / sizeof(ext4_directory_dx_entry_t); 275 275 ext4_directory_dx_countlimit_set_limit(countlimit, root_limit); 276 276 277 277 /* Append new block, where will be new entries inserted in the future */ 278 278 uint32_t iblock; … … 282 282 return rc; 283 283 } 284 284 285 285 block_t *new_block; 286 286 rc = block_get(&new_block, dir->fs->device, fblock, BLOCK_FLAGS_NOREAD); … … 289 289 return rc; 290 290 } 291 291 292 292 /* Fill the whole block with empty entry */ 293 293 ext4_directory_entry_ll_t *block_entry = new_block->data; 294 294 ext4_directory_entry_ll_set_entry_length(block_entry, block_size); 295 295 ext4_directory_entry_ll_set_inode(block_entry, 0); 296 296 297 297 new_block->dirty = true; 298 298 rc = block_put(new_block); … … 301 301 return rc; 302 302 } 303 303 304 304 /* Connect new block to the only entry in index */ 305 305 ext4_directory_dx_entry_t *entry = root->entries; 306 306 ext4_directory_dx_entry_set_block(entry, iblock); 307 307 308 308 block->dirty = true; 309 309 310 310 return block_put(block); 311 311 } … … 328 328 ext4_directory_dx_root_t *root = 329 329 (ext4_directory_dx_root_t *) root_block->data; 330 330 331 331 if ((root->info.hash_version != EXT4_HASH_VERSION_TEA) && 332 332 (root->info.hash_version != EXT4_HASH_VERSION_HALF_MD4) && 333 333 (root->info.hash_version != EXT4_HASH_VERSION_LEGACY)) 334 334 return EXT4_ERR_BAD_DX_DIR; 335 335 336 336 /* Check unused flags */ 337 337 if (root->info.unused_flags != 0) 338 338 return EXT4_ERR_BAD_DX_DIR; 339 339 340 340 /* Check indirect levels */ 341 341 if (root->info.indirect_levels > 1) 342 342 return EXT4_ERR_BAD_DX_DIR; 343 343 344 344 /* Check if node limit is correct */ 345 345 uint32_t block_size = ext4_superblock_get_block_size(sb); … … 348 348 entry_space -= sizeof(ext4_directory_dx_root_info_t); 349 349 entry_space = entry_space / sizeof(ext4_directory_dx_entry_t); 350 350 351 351 uint16_t limit = ext4_directory_dx_countlimit_get_limit( 352 352 (ext4_directory_dx_countlimit_t *) &root->entries); 353 353 if (limit != entry_space) 354 354 return EXT4_ERR_BAD_DX_DIR; 355 355 356 356 /* Check hash version and modify if necessary */ 357 357 hinfo->hash_version = … … 362 362 hinfo->hash_version += 3; 363 363 } 364 364 365 365 /* Load hash seed from superblock */ 366 366 hinfo->seed = ext4_superblock_get_hash_seed(sb); 367 367 368 368 /* Compute hash value of name */ 369 369 if (name) 370 370 ext4_hash_string(hinfo, name_len, name); 371 371 372 372 return EOK; 373 373 } … … 393 393 ext4_directory_dx_entry_t *entries = 394 394 (ext4_directory_dx_entry_t *) &root->entries; 395 395 396 396 uint16_t limit = ext4_directory_dx_countlimit_get_limit( 397 397 (ext4_directory_dx_countlimit_t *) entries); 398 398 uint8_t indirect_level = 399 399 ext4_directory_dx_root_info_get_indirect_levels(&root->info); 400 400 401 401 block_t *tmp_block = root_block; 402 402 ext4_directory_dx_entry_t *p; … … 404 404 ext4_directory_dx_entry_t *m; 405 405 ext4_directory_dx_entry_t *at; 406 406 407 407 /* Walk through the index tree */ 408 408 while (true) { … … 411 411 if ((count == 0) || (count > limit)) 412 412 return EXT4_ERR_BAD_DX_DIR; 413 413 414 414 /* Do binary search in every node */ 415 415 p = entries + 1; 416 416 q = entries + count - 1; 417 417 418 418 while (p <= q) { 419 419 m = p + (q - p) / 2; … … 423 423 p = m + 1; 424 424 } 425 425 426 426 at = p - 1; 427 427 428 428 /* Write results */ 429 429 tmp_dx_block->block = tmp_block; 430 430 tmp_dx_block->entries = entries; 431 431 tmp_dx_block->position = at; 432 432 433 433 /* Is algorithm in the leaf? */ 434 434 if (indirect_level == 0) { … … 436 436 return EOK; 437 437 } 438 438 439 439 /* Goto child node */ 440 440 uint32_t next_block = ext4_directory_dx_entry_get_block(at); 441 441 442 442 indirect_level--; 443 443 444 444 uint32_t fblock; 445 445 errno_t rc = ext4_filesystem_get_inode_data_block_index(inode_ref, … … 447 447 if (rc != EOK) 448 448 return rc; 449 449 450 450 rc = block_get(&tmp_block, inode_ref->fs->device, fblock, 451 451 BLOCK_FLAGS_NONE); 452 452 if (rc != EOK) 453 453 return rc; 454 454 455 455 entries = ((ext4_directory_dx_node_t *) tmp_block->data)->entries; 456 456 limit = ext4_directory_dx_countlimit_get_limit( 457 457 (ext4_directory_dx_countlimit_t *) entries); 458 458 459 459 uint16_t entry_space = 460 460 ext4_superblock_get_block_size(inode_ref->fs->superblock) - 461 461 sizeof(ext4_directory_dx_dot_entry_t); 462 462 entry_space = entry_space / sizeof(ext4_directory_dx_entry_t); 463 463 464 464 if (limit != entry_space) { 465 465 block_put(tmp_block); 466 466 return EXT4_ERR_BAD_DX_DIR; 467 467 } 468 468 469 469 ++tmp_dx_block; 470 470 } 471 471 472 472 /* Unreachable */ 473 473 return EOK; … … 490 490 uint32_t num_handles = 0; 491 491 ext4_directory_dx_block_t *p = dx_block; 492 492 493 493 /* Try to find data block with next bunch of entries */ 494 494 while (true) { … … 496 496 uint16_t count = ext4_directory_dx_countlimit_get_count( 497 497 (ext4_directory_dx_countlimit_t *) p->entries); 498 498 499 499 if (p->position < p->entries + count) 500 500 break; 501 501 502 502 if (p == dx_blocks) 503 503 return EOK; 504 504 505 505 num_handles++; 506 506 p--; 507 507 } 508 508 509 509 /* Check hash collision (if not occured - no next block cannot be used) */ 510 510 uint32_t current_hash = ext4_directory_dx_entry_get_hash(p->position); … … 513 513 return 0; 514 514 } 515 515 516 516 /* Fill new path */ 517 517 while (num_handles--) { … … 519 519 ext4_directory_dx_entry_get_block(p->position); 520 520 uint32_t block_addr; 521 521 522 522 errno_t rc = ext4_filesystem_get_inode_data_block_index(inode_ref, 523 523 block_idx, &block_addr); 524 524 if (rc != EOK) 525 525 return rc; 526 526 527 527 block_t *block; 528 528 rc = block_get(&block, inode_ref->fs->device, block_addr, BLOCK_FLAGS_NONE); 529 529 if (rc != EOK) 530 530 return rc; 531 531 532 532 p++; 533 533 534 534 /* Don't forget to put old block (prevent memory leak) */ 535 535 rc = block_put(p->block); 536 536 if (rc != EOK) 537 537 return rc; 538 538 539 539 p->block = block; 540 540 p->entries = ((ext4_directory_dx_node_t *) block->data)->entries; 541 541 p->position = p->entries; 542 542 } 543 543 544 544 return ENOENT; 545 545 } … … 566 566 if (rc != EOK) 567 567 return rc; 568 568 569 569 ext4_filesystem_t *fs = inode_ref->fs; 570 570 571 571 block_t *root_block; 572 572 rc = block_get(&root_block, fs->device, root_block_addr, … … 574 574 if (rc != EOK) 575 575 return rc; 576 576 577 577 /* Initialize hash info (compute hash value) */ 578 578 ext4_hash_info_t hinfo; … … 583 583 return EXT4_ERR_BAD_DX_DIR; 584 584 } 585 585 586 586 /* 587 587 * Hardcoded number 2 means maximum height of index tree, … … 591 591 ext4_directory_dx_block_t *dx_block; 592 592 ext4_directory_dx_block_t *tmp; 593 593 594 594 rc = ext4_directory_dx_get_leaf(&hinfo, inode_ref, root_block, 595 595 &dx_block, dx_blocks); … … 598 598 return EXT4_ERR_BAD_DX_DIR; 599 599 } 600 600 601 601 do { 602 602 /* Load leaf block */ … … 604 604 ext4_directory_dx_entry_get_block(dx_block->position); 605 605 uint32_t leaf_block_addr; 606 606 607 607 rc = ext4_filesystem_get_inode_data_block_index(inode_ref, 608 608 leaf_block_idx, &leaf_block_addr); 609 609 if (rc != EOK) 610 610 goto cleanup; 611 611 612 612 block_t *leaf_block; 613 613 rc = block_get(&leaf_block, fs->device, leaf_block_addr, … … 615 615 if (rc != EOK) 616 616 goto cleanup; 617 617 618 618 /* Linear search inside block */ 619 619 ext4_directory_entry_ll_t *res_dentry; 620 620 rc = ext4_directory_find_in_block(leaf_block, fs->superblock, 621 621 name_len, name, &res_dentry); 622 622 623 623 /* Found => return it */ 624 624 if (rc == EOK) { … … 627 627 goto cleanup; 628 628 } 629 629 630 630 /* Not found, leave untouched */ 631 631 rc2 = block_put(leaf_block); 632 632 if (rc2 != EOK) 633 633 goto cleanup; 634 634 635 635 if (rc != ENOENT) 636 636 goto cleanup; 637 637 638 638 /* check if the next block could be checked */ 639 639 rc = ext4_directory_dx_next_block(inode_ref, hinfo.hash, … … 643 643 644 644 } while (rc == ENOENT); 645 645 646 646 /* Entry not found */ 647 647 rc = ENOENT; 648 648 649 649 cleanup: 650 650 /* The whole path must be released (preventing memory leak) */ 651 651 tmp = dx_blocks; 652 652 653 653 while (tmp <= dx_block) { 654 654 rc2 = block_put(tmp->block); … … 657 657 ++tmp; 658 658 } 659 659 660 660 return rc; 661 661 } … … 677 677 ext4_dx_sort_entry_t const *entry1 = arg1; 678 678 ext4_dx_sort_entry_t const *entry2 = arg2; 679 679 680 680 if (entry1->hash == entry2->hash) 681 681 return 0; 682 682 683 683 if (entry1->hash < entry2->hash) 684 684 return -1; … … 701 701 ext4_directory_dx_entry_t *old_index_entry = index_block->position; 702 702 ext4_directory_dx_entry_t *new_index_entry = old_index_entry + 1; 703 703 704 704 ext4_directory_dx_countlimit_t *countlimit = 705 705 (ext4_directory_dx_countlimit_t *) index_block->entries; 706 706 uint32_t count = ext4_directory_dx_countlimit_get_count(countlimit); 707 707 708 708 ext4_directory_dx_entry_t *start_index = index_block->entries; 709 709 size_t bytes = (void *) (start_index + count) - (void *) (new_index_entry); 710 710 711 711 memmove(new_index_entry + 1, new_index_entry, bytes); 712 712 713 713 ext4_directory_dx_entry_set_block(new_index_entry, iblock); 714 714 ext4_directory_dx_entry_set_hash(new_index_entry, hash); 715 715 716 716 ext4_directory_dx_countlimit_set_count(countlimit, count + 1); 717 717 718 718 index_block->block->dirty = true; 719 719 } … … 733 733 { 734 734 errno_t rc = EOK; 735 735 736 736 /* Allocate buffer for directory entries */ 737 737 uint32_t block_size = … … 740 740 if (entry_buffer == NULL) 741 741 return ENOMEM; 742 742 743 743 /* dot entry has the smallest size available */ 744 744 uint32_t max_entry_count = 745 745 block_size / sizeof(ext4_directory_dx_dot_entry_t); 746 746 747 747 /* Allocate sort entry */ 748 748 ext4_dx_sort_entry_t *sort_array = … … 752 752 return ENOMEM; 753 753 } 754 754 755 755 uint32_t idx = 0; 756 756 uint32_t real_size = 0; 757 757 758 758 /* Initialize hinfo */ 759 759 ext4_hash_info_t tmp_hinfo; 760 760 memcpy(&tmp_hinfo, hinfo, sizeof(ext4_hash_info_t)); 761 761 762 762 /* Load all valid entries to the buffer */ 763 763 ext4_directory_entry_ll_t *dentry = old_data_block->data; … … 769 769 inode_ref->fs->superblock, dentry); 770 770 ext4_hash_string(&tmp_hinfo, len, (char *) dentry->name); 771 771 772 772 uint32_t rec_len = 8 + len; 773 773 774 774 if ((rec_len % 4) != 0) 775 775 rec_len += 4 - (rec_len % 4); 776 776 777 777 memcpy(entry_buffer_ptr, dentry, rec_len); 778 778 779 779 sort_array[idx].dentry = entry_buffer_ptr; 780 780 sort_array[idx].rec_len = rec_len; 781 781 sort_array[idx].hash = tmp_hinfo.hash; 782 782 783 783 entry_buffer_ptr += rec_len; 784 784 real_size += rec_len; 785 785 idx++; 786 786 } 787 787 788 788 dentry = (void *) dentry + 789 789 ext4_directory_entry_ll_get_entry_length(dentry); 790 790 } 791 791 792 792 /* Sort all entries */ 793 793 qsort(sort_array, idx, sizeof(ext4_dx_sort_entry_t), 794 794 ext4_directory_dx_entry_comparator); 795 795 796 796 /* Allocate new block for store the second part of entries */ 797 797 uint32_t new_fblock; … … 804 804 return rc; 805 805 } 806 806 807 807 /* Load new block */ 808 808 block_t *new_data_block_tmp; … … 814 814 return rc; 815 815 } 816 816 817 817 /* 818 818 * Distribute entries to two blocks (by size) … … 828 828 break; 829 829 } 830 830 831 831 current_size += sort_array[i].rec_len; 832 832 } 833 833 834 834 /* Check hash collision */ 835 835 uint32_t continued = 0; 836 836 if (new_hash == sort_array[mid-1].hash) 837 837 continued = 1; 838 838 839 839 uint32_t offset = 0; 840 840 void *ptr; 841 841 842 842 /* First part - to the old block */ 843 843 for (uint32_t i = 0; i < mid; ++i) { 844 844 ptr = old_data_block->data + offset; 845 845 memcpy(ptr, sort_array[i].dentry, sort_array[i].rec_len); 846 846 847 847 ext4_directory_entry_ll_t *tmp = ptr; 848 848 if (i < (mid - 1)) … … 852 852 ext4_directory_entry_ll_set_entry_length(tmp, 853 853 block_size - offset); 854 854 855 855 offset += sort_array[i].rec_len; 856 856 } 857 857 858 858 /* Second part - to the new block */ 859 859 offset = 0; … … 861 861 ptr = new_data_block_tmp->data + offset; 862 862 memcpy(ptr, sort_array[i].dentry, sort_array[i].rec_len); 863 863 864 864 ext4_directory_entry_ll_t *tmp = ptr; 865 865 if (i < (idx - 1)) … … 869 869 ext4_directory_entry_ll_set_entry_length(tmp, 870 870 block_size - offset); 871 871 872 872 offset += sort_array[i].rec_len; 873 873 } 874 874 875 875 /* Do some steps to finish operation */ 876 876 old_data_block->dirty = true; 877 877 new_data_block_tmp->dirty = true; 878 878 879 879 free(sort_array); 880 880 free(entry_buffer); 881 881 882 882 ext4_directory_dx_insert_entry(index_block, new_hash + continued, 883 883 new_iblock); 884 884 885 885 *new_data_block = new_data_block_tmp; 886 886 887 887 return EOK; 888 888 } … … 907 907 entries = 908 908 ((ext4_directory_dx_node_t *) dx_block->block->data)->entries; 909 909 910 910 ext4_directory_dx_countlimit_t *countlimit = 911 911 (ext4_directory_dx_countlimit_t *) entries; 912 912 913 913 uint16_t leaf_limit = 914 914 ext4_directory_dx_countlimit_get_limit(countlimit); 915 915 uint16_t leaf_count = 916 916 ext4_directory_dx_countlimit_get_count(countlimit); 917 917 918 918 /* Check if is necessary to split index block */ 919 919 if (leaf_limit == leaf_count) { 920 920 size_t levels = dx_block - dx_blocks; 921 921 922 922 ext4_directory_dx_entry_t *root_entries = 923 923 ((ext4_directory_dx_root_t *) dx_blocks[0].block->data)->entries; 924 924 925 925 ext4_directory_dx_countlimit_t *root_countlimit = 926 926 (ext4_directory_dx_countlimit_t *) root_entries; … … 929 929 uint16_t root_count = 930 930 ext4_directory_dx_countlimit_get_count(root_countlimit); 931 931 932 932 /* Linux limitation */ 933 933 if ((levels > 0) && (root_limit == root_count)) 934 934 return ENOSPC; 935 935 936 936 /* Add new block to directory */ 937 937 uint32_t new_fblock; … … 941 941 if (rc != EOK) 942 942 return rc; 943 943 944 944 /* load new block */ 945 945 block_t *new_block; … … 948 948 if (rc != EOK) 949 949 return rc; 950 950 951 951 ext4_directory_dx_node_t *new_node = new_block->data; 952 952 ext4_directory_dx_entry_t *new_entries = new_node->entries; 953 953 954 954 uint32_t block_size = 955 955 ext4_superblock_get_block_size(inode_ref->fs->superblock); 956 956 957 957 /* Split leaf node */ 958 958 if (levels > 0) { … … 961 961 uint32_t hash_right = 962 962 ext4_directory_dx_entry_get_hash(entries + count_left); 963 963 964 964 /* Copy data to new node */ 965 965 memcpy((void *) new_entries, (void *) (entries + count_left), 966 966 count_right * sizeof(ext4_directory_dx_entry_t)); 967 967 968 968 /* Initialize new node */ 969 969 ext4_directory_dx_countlimit_t *left_countlimit = … … 971 971 ext4_directory_dx_countlimit_t *right_countlimit = 972 972 (ext4_directory_dx_countlimit_t *) new_entries; 973 973 974 974 ext4_directory_dx_countlimit_set_count(left_countlimit, count_left); 975 975 ext4_directory_dx_countlimit_set_count(right_countlimit, count_right); 976 976 977 977 uint32_t entry_space = 978 978 block_size - sizeof(ext4_fake_directory_entry_t); … … 980 980 entry_space / sizeof(ext4_directory_dx_entry_t); 981 981 ext4_directory_dx_countlimit_set_limit(right_countlimit, node_limit); 982 982 983 983 /* Which index block is target for new entry */ 984 984 uint32_t position_index = (dx_block->position - dx_block->entries); 985 985 if (position_index >= count_left) { 986 986 dx_block->block->dirty = true; 987 987 988 988 block_t *block_tmp = dx_block->block; 989 989 dx_block->block = new_block; … … 991 991 new_entries + position_index - count_left; 992 992 dx_block->entries = new_entries; 993 993 994 994 new_block = block_tmp; 995 995 } 996 996 997 997 /* Finally insert new entry */ 998 998 ext4_directory_dx_insert_entry(dx_blocks, hash_right, new_iblock); 999 999 1000 1000 return block_put(new_block); 1001 1001 } else { 1002 1002 /* Create second level index */ 1003 1003 1004 1004 /* Copy data from root to child block */ 1005 1005 memcpy((void *) new_entries, (void *) entries, 1006 1006 leaf_count * sizeof(ext4_directory_dx_entry_t)); 1007 1007 1008 1008 ext4_directory_dx_countlimit_t *new_countlimit = 1009 1009 (ext4_directory_dx_countlimit_t *) new_entries; 1010 1010 1011 1011 uint32_t entry_space = 1012 1012 block_size - sizeof(ext4_fake_directory_entry_t); … … 1014 1014 entry_space / sizeof(ext4_directory_dx_entry_t); 1015 1015 ext4_directory_dx_countlimit_set_limit(new_countlimit, node_limit); 1016 1016 1017 1017 /* Set values in root node */ 1018 1018 ext4_directory_dx_countlimit_t *new_root_countlimit = 1019 1019 (ext4_directory_dx_countlimit_t *) entries; 1020 1020 1021 1021 ext4_directory_dx_countlimit_set_count(new_root_countlimit, 1); 1022 1022 ext4_directory_dx_entry_set_block(entries, new_iblock); 1023 1023 1024 1024 ((ext4_directory_dx_root_t *) 1025 1025 dx_blocks[0].block->data)->info.indirect_levels = 1; 1026 1026 1027 1027 /* Add new entry to the path */ 1028 1028 dx_block = dx_blocks + 1; … … 1032 1032 } 1033 1033 } 1034 1034 1035 1035 return EOK; 1036 1036 } … … 1049 1049 { 1050 1050 errno_t rc2 = EOK; 1051 1051 1052 1052 /* Get direct block 0 (index root) */ 1053 1053 uint32_t root_block_addr; … … 1056 1056 if (rc != EOK) 1057 1057 return rc; 1058 1058 1059 1059 ext4_filesystem_t *fs = parent->fs; 1060 1060 1061 1061 block_t *root_block; 1062 1062 rc = block_get(&root_block, fs->device, root_block_addr, … … 1064 1064 if (rc != EOK) 1065 1065 return rc; 1066 1066 1067 1067 /* Initialize hinfo structure (mainly compute hash) */ 1068 1068 uint32_t name_len = str_size(name); … … 1074 1074 return EXT4_ERR_BAD_DX_DIR; 1075 1075 } 1076 1076 1077 1077 /* 1078 1078 * Hardcoded number 2 means maximum height of index … … 1082 1082 ext4_directory_dx_block_t *dx_block; 1083 1083 ext4_directory_dx_block_t *dx_it; 1084 1084 1085 1085 rc = ext4_directory_dx_get_leaf(&hinfo, parent, root_block, 1086 1086 &dx_block, dx_blocks); … … 1089 1089 goto release_index; 1090 1090 } 1091 1091 1092 1092 /* Try to insert to existing data block */ 1093 1093 uint32_t leaf_block_idx = … … 1098 1098 if (rc != EOK) 1099 1099 goto release_index; 1100 1100 1101 1101 block_t *target_block; 1102 1102 rc = block_get(&target_block, fs->device, leaf_block_addr, … … 1104 1104 if (rc != EOK) 1105 1105 goto release_index; 1106 1106 1107 1107 /* Check if insert operation passed */ 1108 1108 rc = ext4_directory_try_insert_entry(fs->superblock, target_block, child, … … 1110 1110 if (rc == EOK) 1111 1111 goto release_target_index; 1112 1112 1113 1113 /* 1114 1114 * Check if there is needed to split index node … … 1118 1118 if (rc != EOK) 1119 1119 goto release_target_index; 1120 1120 1121 1121 /* Split entries to two blocks (includes sorting by hash value) */ 1122 1122 block_t *new_block = NULL; … … 1127 1127 goto release_target_index; 1128 1128 } 1129 1129 1130 1130 /* Where to save new entry */ 1131 1131 uint32_t new_block_hash = … … 1137 1137 rc = ext4_directory_try_insert_entry(fs->superblock, target_block, 1138 1138 child, name, name_len); 1139 1139 1140 1140 /* Cleanup */ 1141 1141 rc = block_put(new_block); 1142 1142 if (rc != EOK) 1143 1143 return rc; 1144 1144 1145 1145 /* Cleanup operations */ 1146 1146 1147 1147 release_target_index: 1148 1148 rc2 = rc; 1149 1149 1150 1150 rc = block_put(target_block); 1151 1151 if (rc != EOK) 1152 1152 return rc; 1153 1153 1154 1154 release_index: 1155 1155 if (rc != EOK) 1156 1156 rc2 = rc; 1157 1157 1158 1158 dx_it = dx_blocks; 1159 1159 1160 1160 while (dx_it <= dx_block) { 1161 1161 rc = block_put(dx_it->block); 1162 1162 if (rc != EOK) 1163 1163 return rc; 1164 1164 1165 1165 dx_it++; 1166 1166 } 1167 1167 1168 1168 return rc2; 1169 1169 }
Note:
See TracChangeset
for help on using the changeset viewer.