Changeset dfac604 in mainline
- Timestamp:
- 2012-04-20T08:43:47Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- bae2a79e
- Parents:
- 1d4262e
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/ext4/libext4_directory_index.c
r1d4262e rdfac604 475 475 ext4_directory_dx_block_t *p = dx_block; 476 476 477 // T ODO comment477 // Try to find data block with next bunch of entries 478 478 while (1) { 479 479 480 480 p->position++; 481 uint16_t count = ext4_directory_dx_countlimit_get_count((ext4_directory_dx_countlimit_t *)p->entries); 481 uint16_t count = ext4_directory_dx_countlimit_get_count( 482 (ext4_directory_dx_countlimit_t *)p->entries); 482 483 483 484 if (p->position < p->entries + count) { … … 493 494 } 494 495 495 // TODO comment496 // Check hash collision (if not occured - no next block cannot be used) 496 497 uint32_t current_hash = ext4_directory_dx_entry_get_hash(p->position); 497 498 if ((hash & 1) == 0) { … … 501 502 } 502 503 503 // TODO comment504 // Fill new path 504 505 while (num_handles--) { 505 506 … … 519 520 p++; 520 521 522 // Don't forget to put old block (prevent memory leak) 521 523 block_put(p->block); 524 522 525 p->block = block; 523 526 p->entries = ((ext4_directory_dx_node_t *) block->data)->entries; … … 852 855 } 853 856 854 /** TODO start comments from here 855 * 856 */ 857 static int ext4_directory_dx_split_index(ext4_filesystem_t *fs, 858 ext4_inode_ref_t *inode_ref, ext4_directory_dx_block_t *dx_blocks, 859 ext4_directory_dx_block_t *dx_block) 857 /** Split index node and maybe some parent nodes in the tree hierarchy. 858 * 859 * @param inode_ref directory i-node 860 * @param dx_blocks array with path from root to leaf node 861 * @param dx_block leaf block to be split if needed 862 * @return error code 863 */ 864 static int ext4_directory_dx_split_index(ext4_inode_ref_t *inode_ref, 865 ext4_directory_dx_block_t *dx_blocks, ext4_directory_dx_block_t *dx_block) 860 866 { 861 867 int rc; … … 875 881 // Check if is necessary to split index block 876 882 if (leaf_limit == leaf_count) { 877 EXT4FS_DBG("need to split index block !!!");878 883 879 884 unsigned int levels = dx_block - dx_blocks; … … 889 894 ext4_directory_dx_countlimit_get_count(root_countlimit); 890 895 896 // Linux limitation 891 897 if ((levels > 0) && (root_limit == root_count)) { 892 898 EXT4FS_DBG("Directory index is full"); … … 894 900 } 895 901 902 // Add new block to directory 896 903 uint32_t new_fblock; 897 904 uint32_t new_iblock; … … 902 909 } 903 910 904 // New block allocated911 // load new block 905 912 block_t * new_block; 906 rc = block_get(&new_block, fs->device, new_fblock, BLOCK_FLAGS_NOREAD); 913 rc = block_get(&new_block, inode_ref->fs->device, 914 new_fblock, BLOCK_FLAGS_NOREAD); 907 915 if (rc != EOK) { 908 916 return rc; … … 912 920 ext4_directory_dx_entry_t *new_entries = new_node->entries; 913 921 914 uint32_t block_size = ext4_superblock_get_block_size(fs->superblock); 915 922 uint32_t block_size = ext4_superblock_get_block_size( 923 inode_ref->fs->superblock); 924 925 // Split leaf node 916 926 if (levels > 0) { 917 EXT4FS_DBG("split index leaf node"); 927 918 928 uint32_t count_left = leaf_count / 2; 919 929 uint32_t count_right = leaf_count - count_left; … … 921 931 ext4_directory_dx_entry_get_hash(entries + count_left); 922 932 933 // Copy data to new node 923 934 memcpy((void *) new_entries, (void *) (entries + count_left), 924 935 count_right * sizeof(ext4_directory_dx_entry_t)); 925 936 937 // Initialize new node 926 938 ext4_directory_dx_countlimit_t *left_countlimit = 927 939 (ext4_directory_dx_countlimit_t *)entries; … … 951 963 } 952 964 965 // Finally insert new entry 953 966 ext4_directory_dx_insert_entry(dx_blocks, hash_right, new_iblock); 954 967 … … 956 969 957 970 } else { 958 EXT4FS_DBG("create second level"); 959 971 972 // Create second level index 973 974 // Copy data from root to child block 960 975 memcpy((void *) new_entries, (void *) entries, 961 976 leaf_count * sizeof(ext4_directory_dx_entry_t)); … … 977 992 ((ext4_directory_dx_root_t *)dx_blocks[0].block->data)->info.indirect_levels = 1; 978 993 979 / * Add new access path frame */994 // Add new entry to the path 980 995 dx_block = dx_blocks + 1; 981 996 dx_block->position = dx_block->position - entries + new_entries; … … 989 1004 } 990 1005 1006 /** Add new entry to indexed directory 1007 * 1008 * @param parent directory i-node 1009 * @param child i-node to be referenced from directory entry 1010 * @param name name of new directory entry 1011 * @return error code 1012 */ 991 1013 int ext4_directory_dx_add_entry(ext4_inode_ref_t *parent, 992 1014 ext4_inode_ref_t *child, const char *name) … … 1010 1032 } 1011 1033 1034 // Initialize hinfo structure (mainly compute hash) 1012 1035 uint32_t name_len = strlen(name); 1013 1036 ext4_hash_info_t hinfo; … … 1019 1042 } 1020 1043 1021 // Hardcoded number 2 means maximum height of index tree !!!1044 // Hardcoded number 2 means maximum height of index tree defined in linux 1022 1045 ext4_directory_dx_block_t dx_blocks[2]; 1023 1046 ext4_directory_dx_block_t *dx_block, *dx_it; … … 1045 1068 } 1046 1069 1047 1070 // Check if insert operation passed 1048 1071 rc = ext4_directory_try_insert_entry(fs->superblock, target_block, child, name, name_len); 1049 1072 if (rc == EOK) { … … 1051 1074 } 1052 1075 1053 EXT4FS_DBG("no free space found");1054 1055 rc = ext4_directory_dx_split_index( fs,parent, dx_blocks, dx_block);1076 // Check if there is needed to split index node 1077 // (and recursively also parent nodes) 1078 rc = ext4_directory_dx_split_index(parent, dx_blocks, dx_block); 1056 1079 if (rc != EOK) { 1057 1080 goto release_target_index; 1058 1081 } 1059 1082 1083 // Split entries to two blocks (includes sorting by hash value) 1060 1084 block_t *new_block = NULL; 1061 1085 rc = ext4_directory_dx_split_data(parent, &hinfo, target_block, dx_block, &new_block); … … 1073 1097 } 1074 1098 1075 1076 1077 1099 // Cleanup 1078 1100 rc = block_put(new_block); 1079 1101 if (rc != EOK) { … … 1081 1103 return rc; 1082 1104 } 1105 1106 // Cleanup operations 1083 1107 1084 1108 release_target_index:
Note:
See TracChangeset
for help on using the changeset viewer.