📄 fsckdtre.c
字号:
* object whose inode number is given. * * PARAMETERS: * child_inonum - input - the inode number in the directory entry * dtstbl - input - pointer to the sorted entry index table * in the directory node * slots - input - pointer to slot[0] in the directory node * last_dtidx - input - last valid entry in the directory * node's sorted entry index table * found_name_length - input - pointer to a variable in which to return * the length of the filename being returned * in *found_name * found_name - input - pointer to a buffer in which to return * the filename extracted from the node * entry_found - input - pointer to a variable in which to return * !0 if an entry is found with inode number * child_inonum * 0 if no entry is found with inode number * child_inonum * * RETURNS: * success: FSCK_OK * failure: something else */int direntry_get_objnam_node(uint32_t child_inonum, int8_t * dtstbl, struct dtslot *slots, int last_dtidx, int *found_name_length, UniChar * found_name, int8_t * entry_found){ int dgonn_rc = FSCK_OK; int dtidx; struct ldtentry *entry_ptr = NULL; struct dtslot *contin_entry_ptr; int seg_length, UniChars_left, seg_max; if (sb_ptr->s_flag & JFS_DIR_INDEX) seg_max = DTLHDRDATALEN; else seg_max = DTLHDRDATALEN_LEGACY; /* assume it's not here */ *entry_found = 0; /* * see if this leaf has the entry for the requested child */ for (dtidx = 0; ((dgonn_rc == FSCK_OK) && (dtidx <= last_dtidx) && (!(*entry_found))); dtidx++) { /* for each entry in the dtstbl index to slots */ entry_ptr = (struct ldtentry *) &(slots[dtstbl[dtidx]]); if (entry_ptr->inumber == child_inonum) { *entry_found = -1; } } /* * if the child's entry was found, construct its name */ if (*entry_found) { /* the child's entry was found */ UniChars_left = entry_ptr->namlen; if (UniChars_left > seg_max) { seg_length = seg_max; UniChars_left -= seg_max; } else { seg_length = UniChars_left; UniChars_left = 0; } memcpy((void *) &(found_name[*found_name_length]), (void *) &(entry_ptr->name[0]), (size_t) (seg_length * sizeof (UniChar)) ); *found_name_length = seg_length; if (entry_ptr->next != -1) { /* name is continued */ contin_entry_ptr = (struct dtslot *) &(slots[entry_ptr->next]); } else { contin_entry_ptr = NULL; } seg_max = DTSLOTDATALEN; while ((contin_entry_ptr != NULL) && ((*found_name_length) <= JFS_NAME_MAX)) { /* name is continued */ if (UniChars_left > seg_max) { seg_length = seg_max; UniChars_left -= seg_max; } else { seg_length = UniChars_left; UniChars_left = 0; } memcpy((void *) &(found_name[*found_name_length]), (void *) &(contin_entry_ptr->name[0]), (size_t) (seg_length * sizeof (UniChar)) ); *found_name_length += seg_length; if (contin_entry_ptr->next != -1) { /* still more */ contin_entry_ptr = (struct dtslot *) &(slots[contin_entry_ptr->next]); } else { contin_entry_ptr = NULL; } } if (contin_entry_ptr != NULL) { dgonn_rc = FSCK_FAILED_DIRGONEBAD2; } } return (dgonn_rc);}/***************************************************************************** * NAME: direntry_remove * * FUNCTION: Issue an fsck message, depending on the message's protocol * according to the fsck message arrays (above). Log the * message to fscklog if logging is in effect. * * PARAMETERS: * parent_inoptr - input - pointer to the directory inode in an fsck * buffer * child_inonum - input - the inode number in the directory entry * * RETURNS: * success: FSCK_OK * failure: something else */int direntry_remove(struct dinode *parent_inoptr, uint32_t child_inonum){ int rd_rc = FSCK_OK; UniChar uniname[JFS_NAME_MAX]; int uniname_length; struct component_name uniname_struct; rd_rc = direntry_get_objnam(parent_inoptr->di_number, child_inonum, &uniname_length, &(uniname[0])); if (rd_rc == FSCK_OK) { uniname_struct.namlen = uniname_length; uniname_struct.name = &(uniname[0]); rd_rc = fsck_dtDelete(parent_inoptr, &uniname_struct, &child_inonum); if (rd_rc == FSCK_OK) { rd_rc = inode_put(parent_inoptr); } else { fsck_send_msg(fsck_INTERNALERROR, FSCK_INTERNAL_ERROR_61, rd_rc, child_inonum, parent_inoptr->di_number); rd_rc = FSCK_INTERNAL_ERROR_61; } } else { fsck_send_msg(fsck_INTERNALERROR, FSCK_INTERNAL_ERROR_62, rd_rc, child_inonum, parent_inoptr->di_number); rd_rc = FSCK_INTERNAL_ERROR_62; } return (rd_rc);}/***************************************************************************** * NAME: dTree_binsrch_internal_page * * FUNCTION: Perform a binary search, on the given dTree internal node, for * the entry which is parent/grandparent/... to the leaf entry * containing the given filename. * * PARAMETERS: * dtiptr - input - pointer to an fsck record describing the * directory tree * given_name - input - pointer to the name to search for * given_name_len - input - number of characters in given_name * is_root - input - !0 => specified node is a B+ Tree root * 0 => specified node is not a B+ Tree root * no_key_match - input - pointer to a variable in which to return * an indication of whether the search has * been completed because it has been * determined that no entry in the directory * matches given_name * !0 if the search should be ended, No * match found * 0 if either the search should continue or * a match has been found * slot_selected - input - pointer to a variable in which to return * an indication of whether the search has * been completed at this level by finding * a match, a prefix match, or reason to * believe we may still find a match. * !0 if a slot has been selected * 0 if either the search should continue or * it has been determined that there is * no match in the directory * selected_slotidx - input - pointer to a variable in which to return * the number n such that slot[n] contains * (or begins) the key which is a match or * a prefix match for given_name * inorecptr - input - pointer to an fsck inode record describing * the inode * * RETURNS: * success: FSCK_OK * failure: something else */int dTree_binsrch_internal_page(struct fsck_Dtree_info *dtiptr, UniChar * given_name, uint32_t given_name_len, int8_t is_root, int8_t * no_key_match, int8_t * slot_selected, int8_t * selected_slotidx, struct fsck_inode_record *inorecptr){ int dbip_rc = FSCK_OK; UniChar *this_name; uint32_t *this_name_len; int lowidx, mididx, highidx; int prev_idx, next_idx; int8_t is_leaf = 0; int outcome; this_name = &(key[1][0]); this_name_len = &(key_len[1]); *no_key_match = 0; *slot_selected = 0; *selected_slotidx = 0; lowidx = 0; highidx = dtiptr->last_dtidx; dbip_rc = dTree_key_extract(dtiptr, lowidx, this_name, this_name_len, is_root, is_leaf, inorecptr); /* * note that we can proceed with (some) confidence since we never * search a directory until after we've verified it's structure */ if (dbip_rc == FSCK_OK) { dbip_rc = dTree_key_compare(given_name, given_name_len, this_name, (*this_name_len), &outcome); if (outcome == LEFT_KEY_LOWER) { /* given key < 1st in this node */ *no_key_match = -1; } else if (outcome == KEYS_MATCH) { /* given key == 1st in this node */ *slot_selected = -1; *selected_slotidx = dtiptr->dtstbl[lowidx]; } else { /* given key > 1st in this node */ dbip_rc = dTree_key_extract(dtiptr, highidx, this_name, this_name_len, is_root, is_leaf, inorecptr); /* * note that we can proceed with (some) confidence * since we never search a directory until after we've * verified it's structure */ if (dbip_rc == FSCK_OK) { dbip_rc = dTree_key_compare(given_name, given_name_len, this_name, (*this_name_len), &outcome); if (outcome == LEFT_KEY_HIGHER) { /* given key > last in the node */ *slot_selected = -1; *selected_slotidx = dtiptr->dtstbl[highidx]; } else if (outcome == KEYS_MATCH) { *slot_selected = -1; *selected_slotidx = dtiptr->dtstbl[highidx]; } } } } /* * Find the first key equal or, if no exact match exists, find the * last key lower. */ while ((!(*slot_selected)) && (!(*no_key_match)) && (dbip_rc == FSCK_OK)) { /* haven't chosen one but haven't ruled anything out */ mididx = ((highidx - lowidx) >> 1) + lowidx; dbip_rc = dTree_key_extract(dtiptr, mididx, this_name, this_name_len, is_root, is_leaf, inorecptr); /* * note that we can proceed with (some) confidence since we never * search a directory until after we've verified it's structure */ if (dbip_rc == FSCK_OK) { dbip_rc = dTree_key_compare(given_name, given_name_len, this_name, (*this_name_len), &outcome); if (dbip_rc == FSCK_OK) { if (outcome == KEYS_MATCH) { /* given name == mid key */ *slot_selected = -1; *selected_slotidx = dtiptr->dtstbl[mididx]; } else if (outcome == LEFT_KEY_HIGHER) { /* given name > mid key */ next_idx = mididx + 1; dbip_rc = dTree_key_extract(dtiptr, next_idx, this_name, this_name_len, is_root, is_leaf, inorecptr); /* * note that we can proceed with (some) * confidence since we never search a directory * until after we've verified it's structure */ if (dbip_rc == FSCK_OK) { /* got next key */ dbip_rc = dTree_key_compare (given_name, given_name_len, this_name, (*this_name_len), &outcome); if (dbip_rc == FSCK_OK) { if (outcome == LEFT_KEY_LOWER) { /* the next one is higher */ *slot_selected = -1; *selected_slotidx = dtiptr-> dtstbl [mididx]; } else if (outcome == KEYS_MATCH) { /* since we've done the * extract and compare might as well see if * we lucked into a match */ *slot_selected = -1; *selected_slotidx = dtiptr-> dtstbl [next_idx]; } else { /* not on or just before the money */ /* this key is higher than the middle */ lowidx = mididx; } } } } else { /* given name < mid key */ prev_idx = mididx - 1; dbip_rc = dTree_key_extract(dtiptr, prev_idx, this_name, this_name_len, is_root, is_leaf, inorecptr); /* * note that we can proceed with (some) * confidence since we never search a directory * until after we've verified it's structure */ if (dbip_rc == FSCK_OK) { dbip_rc = dTree_key_compare (given_name, given_name_len, this_name, (*this_name_len), &outcome); if (dbip_rc == FSCK_OK) { if (outcome == LEFT_KEY_HIGHER) { /* the prev one is lower */ *slot_selected = -1; *selected_slotidx = dtiptr-> dtstbl [prev_idx]; } else if (outcome == KEYS_MATCH) { /* since we've done the * extract and compare might as well see if * we stumbled onto a match */ *slot_selected = -1; *selected_slotidx = dtiptr-> dtstbl [prev_idx]; } else { /* not on or just after the money */ /* this key is lower than the middle */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -