📄 fsckdtre.c
字号:
(unsigned short) NULL) { inorecptr->ignore_alloc_blks = 1; } else { this_charidx++; } } return (deck_rc);}/***************************************************************************** * NAME: dTree_key_extract_record * * FUNCTION: Extract the specified directory entry (either internal or * leaf) key and concatenate it's segments (if more than one). * Directory structure validation is in progress. * * PARAMETERS: * dtiptr - input - pointer to an fsck record describing the * directory tree * start_dtidx - input - index of the entry in the directory node's * sorted entry index table containing the * slot number of the (first segment of the) * key to extract * key_space - input - pointer to a buffer in which to return * the directory key (a complete filename if * the node is a leaf) extracted * key_length - input - pointer to a variable in which to return * the length of the directory key being returned * in *key_space * is_root - input - !0 => the specified node is a B+ Tree root * 0 => the specified node is not a B+ Tree root * is_leaf - input - !0 => the specified node is a leaf node * 0 => the specified node is not a leaf node * inorecptr - input - pointer to an fsck inode record describing * the inode * * RETURNS: * success: FSCK_OK * failure: something else */int dTree_key_extract_record(struct fsck_Dtree_info *dtiptr, int start_dtidx, UniChar * key_space, uint32_t * key_length, int8_t is_root, int8_t is_leaf, struct fsck_inode_record *inorecptr){ int derk_rc = FSCK_OK; int this_slotidx, next_slotidx, this_charidx; struct idtentry *ientry_ptr; struct ldtentry *lentry_ptr; UniChar *name_seg; int seg_length, UniChars_left = 0, seg_max; struct dtslot *contin_entry_ptr; this_slotidx = dtiptr->dtstbl[start_dtidx]; if (is_leaf) { lentry_ptr = (struct ldtentry *) &(dtiptr->slots[this_slotidx]); name_seg = &(lentry_ptr->name[0]); *key_length = lentry_ptr->namlen; next_slotidx = lentry_ptr->next; if (sb_ptr->s_flag & JFS_DIR_INDEX) seg_max = DTLHDRDATALEN; else seg_max = DTLHDRDATALEN_LEGACY; } else { ientry_ptr = (struct idtentry *) &(dtiptr->slots[this_slotidx]); name_seg = &(ientry_ptr->name[0]); *key_length = ientry_ptr->namlen; next_slotidx = ientry_ptr->next; seg_max = DTIHDRDATALEN; } if ((*key_length) > JFS_NAME_MAX) { /* name too long */ inorecptr->ignore_alloc_blks = 1; } else { UniChars_left = *key_length; *key_length = 0; } while ((derk_rc == FSCK_OK) && (this_slotidx != -1) && (!inorecptr->ignore_alloc_blks)) { if ((this_slotidx > dtiptr->max_slotidx) || (this_slotidx < DTENTRYSTART) || (dtiptr->slot_map[this_slotidx] != 0)) { /* index is out of bounds OR index was seen in a previous key chain */ /* bad chain */ inorecptr->ignore_alloc_blks = 1; } else { /* else no reason to think there's a problem */ /* mark the slot used */ dtiptr->slot_map[this_slotidx] = -1; if (UniChars_left > seg_max) { /* this isn't the last */ seg_length = seg_max; UniChars_left = UniChars_left - seg_max; } else { seg_length = UniChars_left; UniChars_left = 0; } /* copy this section of the name into the buffer */ memcpy((void *) &(key_space[*key_length]), (void *) &(name_seg[0]), (seg_length * sizeof (UniChar))); *key_length += seg_length; this_slotidx = next_slotidx; if (next_slotidx != -1) { /* it's not the end of chain marker */ if (UniChars_left == 0) /* too many segments */ inorecptr->ignore_alloc_blks = 1; else { contin_entry_ptr = &(dtiptr->slots[this_slotidx]); name_seg = &(contin_entry_ptr->name[0]); seg_length = contin_entry_ptr->cnt; next_slotidx = contin_entry_ptr->next; seg_max = DTSLOTDATALEN; } } } } /* * check for a null character embedded in the name */ this_charidx = 0; while ((derk_rc == FSCK_OK) && (!inorecptr->ignore_alloc_blks) && (this_charidx < *key_length)) { if (((unsigned short *) key_space)[this_charidx] == (unsigned short) NULL) { inorecptr->ignore_alloc_blks = 1; } else { this_charidx++; } } return (derk_rc);}/***************************************************************************** * NAME: dTree_key_to_upper * * FUNCTION: Fold the given mixed-case string to upper case. * * PARAMETERS: * given_name - input - pointer to the name which is to be folded to * upper case * name_in_upper - input - pointer to a buffer in which to return the * string which results from folding given_name * to upper case * name_len - input - the number of UniChars in given_name * * RETURNS: * success: FSCK_OK * failure: something else */int dTree_key_to_upper(UniChar * given_name, UniChar * name_in_upper, int32_t name_len){ int dktu_rc = FSCK_OK; int charidx; for (charidx = 0; (charidx < name_len); charidx++) { if (sb_ptr->s_flag & JFS_OS2) /* only upper case if case-insensitive support is wanted */ name_in_upper[charidx] = UniToupper(given_name[charidx]); else name_in_upper[charidx] = given_name[charidx]; } return (dktu_rc);}/***************************************************************************** * NAME: dTree_node_first_key * * FUNCTION: Assists dTree_processing. * * PARAMETERS: * dtiptr - input - pointer to an fsck record describing the * directory tree * inorecptr - input - pointer to an fsck inode record describing * the inode * msg_info_ptr - input - pointer to data needed to issue messages * about the inode * desired_action - input - { FSCK_RECORD | FSCK_RECORD_DUPCHECK | * FSCK_UNRECORD | FSCK_QUERY } * * RETURNS: * success: FSCK_OK * failure: something else */int dTree_node_first_key(struct fsck_Dtree_info *dtiptr, struct fsck_inode_record *inorecptr, struct fsck_ino_msg_info *msg_info_ptr, int desired_action){ int dnfk_rc = FSCK_OK; int8_t keys_ok; dnfk_rc = dTree_key_compare_prntchld(dtiptr, &(dtiptr->this_Qel->node_key[0]), dtiptr->this_Qel->node_key_len, &(dtiptr-> key[dtiptr->this_key_idx][0]), dtiptr->key_len[dtiptr-> this_key_idx], &keys_ok); if (dnfk_rc == FSCK_OK) { if (!keys_ok) { /* invalid key in first slot */ inorecptr->ignore_alloc_blks = 1; if (desired_action == FSCK_RECORD_DUPCHECK) { /* not reported yet */ fsck_send_msg(fsck_BADKEYS, fsck_ref_msg(msg_info_ptr->msg_inotyp), fsck_ref_msg(msg_info_ptr->msg_inopfx), msg_info_ptr->msg_inonum, 1); } } else { /* 1st slot may be ok */ if (dtiptr->last_level == dtiptr->this_Qel->node_level) { /* * the node is not 1st in its level */ if (dtiptr->leaf_level == dtiptr->this_Qel->node_level) { /* it's a leaf */ dnfk_rc = dTree_key_compare_leaflvl(&(dtiptr-> key [dtiptr-> last_key_idx] [0]), dtiptr-> key_len [dtiptr-> last_key_idx], &(dtiptr-> key [dtiptr-> this_key_idx] [0]), dtiptr-> key_len [dtiptr-> this_key_idx], &keys_ok); } else { /* not a leaf */ dnfk_rc = dTree_key_compare_samelvl(&(dtiptr-> key [dtiptr-> last_key_idx] [0]), dtiptr-> key_len [dtiptr-> last_key_idx], &(dtiptr-> key [dtiptr-> this_key_idx] [0]), dtiptr-> key_len [dtiptr-> this_key_idx], &keys_ok); } if (!keys_ok) { /* keys out of sort order! */ inorecptr->ignore_alloc_blks = 1; if (desired_action == FSCK_RECORD_DUPCHECK) { /* not reported */ fsck_send_msg(fsck_BADKEYS, fsck_ref_msg(msg_info_ptr->msg_inotyp), fsck_ref_msg(msg_info_ptr->msg_inopfx), msg_info_ptr->msg_inonum, 2); } } } } } return (dnfk_rc);}/***************************************************************************** * NAME: dTree_node_first_in_level * * FUNCTION: Assists dTree_processing. * * PARAMETERS: * dtiptr - input - pointer to an fsck record describing the * directory tree * inorecptr - input - pointer to an fsck inode record describing * the inode * msg_info_ptr - input - pointer to data needed to issue messages * about the inode * desired_action - input - { FSCK_RECORD | FSCK_RECORD_DUPCHECK | * FSCK_UNRECORD | FSCK_QUERY } * * RETURNS: * success: FSCK_OK * failure: something else */int dTree_node_first_in_level(struct fsck_Dtree_info *dtiptr, struct fsck_inode_record *inorecptr, struct fsck_ino_msg_info *msg_info_ptr, int desired_action){ int dnfil_rc = FSCK_OK; if (dtiptr->dtp_ptr->header.prev != 0) { /* bad back pointer! */ inorecptr->ignore_alloc_blks = 1; if (desired_action == FSCK_RECORD_DUPCHECK) { /* not reported */ fsck_send_msg(fsck_BADBSBLCHN, fsck_ref_msg(msg_info_ptr->msg_inotyp), fsck_ref_msg(msg_info_ptr->msg_inopfx), msg_info_ptr->msg_inonum); } } return (dnfil_rc);}/***************************************************************************** * NAME: dTree_node_last_in_level * * FUNCTION: Assists dTree_processing. * * PARAMETERS: * dtiptr - input - pointer to an fsck record describing the * directory tree * inorecptr - input - pointer to an fsck inode record describing * the inode * msg_info_ptr - input - pointer to data needed to issue messages * about the inode * desired_action - input - { FSCK_RECORD | FSCK_RECORD_DUPCHECK | * FSCK_UNRECORD | FSCK_QUERY } * * RETURNS: * success: FSCK_OK * failure: something else */int dTree_node_last_in_level(struct fsck_Dtree_info *dtiptr, struct fsck_inode_record *inorecptr, struct fsck_ino_msg_info *msg_info_ptr, int desired_action){ int dnlil_rc = FSCK_OK; if (dtiptr->dtp_ptr->header.next != 0) { /* bad forward pointer! */ inorecptr->ignore_alloc_blks = 1; if (desired_action == FSCK_RECORD_DUPCHECK) { /* not reported */ fsck_send_msg(fsck_BADFSBLCHN, fsck_ref_msg(msg_info_ptr->msg_inotyp), fsck_ref_msg(msg_info_ptr->msg_inopfx), msg_info_ptr->msg_inonum); } } return (dnlil_rc);}/***************************************************************************** * NAME: dTree_node_not_first_in_level * * FUNCTION: Assists dTree_processing. * * PARAMETERS: * dtiptr - input - pointer to an fsck record describing the * directory tree * inorecptr - input - pointer to an fsck inode record describing * the inode * msg_info_ptr - input - pointer to data needed to issue messages * about the inode * desired_action - input - { FSCK_RECORD | FSCK_RECORD_DUPCHECK | * FSCK_UNRECORD | FSCK_QUERY } * * RETURNS: * success: FSCK_OK * failure: something else */int dTree_node_not_first_in_level(struct fsck_Dtree_info *dtiptr, struct fsck_inode_record *inorecptr, struct fsck_ino_msg_info *msg_info_ptr, int desired_action){ int dnnfil_rc = FSCK_OK; if (dtiptr->dtp_ptr->header.p
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -