📄 fsckxtre.c
字号:
*/ } else { /* root is not a leaf */ if (xtiptr->xtp_ptr->header.flag & BT_INTERNAL) { /* root internal */ xp_rc = xTree_process_internal_extents (xtiptr->xtp_ptr, inorecptr, xtiptr->this_Qel, msg_info_ptr, desired_action); } else { /* invalid flag value! */ inorecptr->ignore_alloc_blks = 1; if (desired_action == FSCK_RECORD_DUPCHECK) { /* not reported yet */ fsck_send_msg(fsck_BADINOOTHR, "50", fsck_ref_msg(msg_info_ptr->msg_inotyp), fsck_ref_msg(msg_info_ptr->msg_inopfx), msg_info_ptr->msg_inonum); } } } while ((xp_rc == FSCK_OK) && (!inorecptr->ignore_alloc_blks) && (agg_recptr->treeQ_back != NULL)) { /* nothing fatal and tree looks ok and queue not empty */ xp_rc = treeQ_dequeue(&xtiptr->next_Qel); if (xp_rc != FSCK_OK) break; if (xtiptr->this_Qel->node_level == xtiptr->next_Qel->node_level) /* it's not the last in its level */ xp_rc = xTree_node_not_last_in_level(xtiptr, inorecptr, msg_info_ptr, desired_action); else if (!is_root) /* it is the last in its level */ xp_rc = xTree_node_last_in_level(xtiptr, inorecptr, msg_info_ptr, desired_action); if ((xp_rc != FSCK_OK) || inorecptr->ignore_alloc_blks) break; /* * save some info about the node already processed * and then move on to the new node */ xtiptr->last_level = xtiptr->this_Qel->node_level; xtiptr->last_node_addr = xtiptr->this_Qel->node_addr; xtiptr->xad_ptr = &(xtiptr-> xtp_ptr->xad[xtiptr->xtp_ptr->header.nextindex - 1]); if (xtiptr->xtp_ptr->header.flag & BT_LEAF) { /* it's a leaf */ xtiptr->last_key = offsetXAD(xtiptr->xad_ptr) + lengthXAD(xtiptr->xad_ptr) - 1; } else { /* it's an internal node */ xtiptr->last_key = offsetXAD(xtiptr->xad_ptr); } xp_rc = treeQ_rel_elem(xtiptr->this_Qel); if (xp_rc != FSCK_OK) break; /* released the older element */ /* promote newer element */ xtiptr->this_Qel = xtiptr->next_Qel; /* to avoid releasing it twice */ xtiptr->next_Qel = NULL; is_root = 0; xp_rc = node_get(xtiptr->this_Qel->node_addr, &xtiptr->xtp_ptr); if (xp_rc != FSCK_OK) { /* bad read! */ inorecptr->ignore_alloc_blks = 1; if (desired_action == FSCK_RECORD_DUPCHECK) { /* not reported yet */ fsck_send_msg(fsck_BADINOOTHR, "42", fsck_ref_msg(msg_info_ptr->msg_inotyp), fsck_ref_msg(msg_info_ptr->msg_inopfx), msg_info_ptr->msg_inonum); } break; } /* got the new node */ if (xtiptr->xtp_ptr->header.maxentry != XTPAGEMAXSLOT) { /* bad maxentry field */ inorecptr->ignore_alloc_blks = 1; if (desired_action == FSCK_RECORD_DUPCHECK) { /* not reported yet */ fsck_send_msg(fsck_BADINOOTHR, "43", fsck_ref_msg(msg_info_ptr->msg_inotyp), fsck_ref_msg(msg_info_ptr->msg_inopfx), msg_info_ptr->msg_inonum); } } else if (xtiptr->xtp_ptr->header.nextindex > xtiptr->xtp_ptr->header.maxentry) { /* bad nextindex field */ inorecptr->ignore_alloc_blks = 1; if (desired_action == FSCK_RECORD_DUPCHECK) { /* not reported yet */ fsck_send_msg(fsck_BADINOOTHR, "44", fsck_ref_msg(msg_info_ptr->msg_inotyp), fsck_ref_msg(msg_info_ptr->msg_inopfx), msg_info_ptr->msg_inonum); } } if (inorecptr->ignore_alloc_blks) break; if (xtiptr->last_level != xtiptr->this_Qel->node_level) { /* this is a new level */ xtiptr->last_key = 0; xp_rc = xTree_node_first_in_level (xtiptr, inorecptr, msg_info_ptr, desired_action); } else { xp_rc = xTree_node_not_first_in_level (xtiptr, inorecptr, msg_info_ptr, desired_action); } ixpxd_unequal = memcmp((void *) &(xtiptr->xtp_ptr->header.self), (void *) &(xtiptr->this_Qel->node_pxd), sizeof (pxd_t)); if (ixpxd_unequal) { /* bad self field in header */ inorecptr->ignore_alloc_blks = 1; if (desired_action == FSCK_RECORD_DUPCHECK) { /* not reported yet */ fsck_send_msg(fsck_BADINONODESELF, fsck_ref_msg(msg_info_ptr->msg_inotyp), fsck_ref_msg(msg_info_ptr->msg_inopfx), msg_info_ptr->msg_inonum); } } else if (xtiptr->xtp_ptr->header.nextindex > XTENTRYSTART) { if (xtiptr->xtp_ptr->header.flag & BT_LEAF) { /* it's a leaf */ xtiptr->xad_ptr = & (xtiptr->xtp_ptr->xad [xtiptr->xtp_ptr->header.nextindex - 1]); agg_recptr->this_inode.data_size = (int64_t) (offsetXAD (xtiptr->xad_ptr) + lengthXAD (xtiptr->xad_ptr)) * sb_ptr->s_bsize; /* * Just in case this is the * last leaf for the inode */ } xtiptr->xad_ptr = &(xtiptr->xtp_ptr->xad[XTENTRYSTART]); xtiptr->this_key = offsetXAD(xtiptr->xad_ptr); xtiptr->ext_length = lengthXAD(xtiptr->xad_ptr); } else { /* an empty non-root node */ inorecptr->ignore_alloc_blks = 1; if (desired_action == FSCK_RECORD_DUPCHECK) { /* not reported yet */ fsck_send_msg(fsck_BADINOMTNODE, fsck_ref_msg(msg_info_ptr->msg_inotyp), fsck_ref_msg(msg_info_ptr->msg_inopfx), msg_info_ptr->msg_inonum); } } if ((xp_rc != FSCK_OK) || inorecptr->ignore_alloc_blks) break; xp_rc = xTree_node_first_key(xtiptr, inorecptr, msg_info_ptr, desired_action); if ((xp_rc != FSCK_OK) || inorecptr->ignore_alloc_blks) break; if (xtiptr->xtp_ptr->header.flag & BT_LEAF) { /* a leaf node */ if (not_fsim_tree) { /* not the FileSet Inode Map tree */ xp_rc = xTree_process_leaf_extents (xtiptr->xtp_ptr, inorecptr, xtiptr->this_Qel, msg_info_ptr, xtiptr->dense_file, desired_action); } } else { /* not a leaf node */ if (xtiptr->xtp_ptr->header.flag & BT_INTERNAL) { /* an internal node */ xp_rc = xTree_process_internal_extents (xtiptr->xtp_ptr, inorecptr, xtiptr->this_Qel, msg_info_ptr, desired_action); } else { /* an invalid flag value! */ inorecptr->ignore_alloc_blks = 1; if (desired_action == FSCK_RECORD_DUPCHECK) { /* not reported yet */ fsck_send_msg(fsck_BADINOOTHR, "51", fsck_ref_msg(msg_info_ptr->msg_inotyp), fsck_ref_msg(msg_info_ptr->msg_inopfx), msg_info_ptr->msg_inonum); } } } if ((xp_rc == FSCK_OK) && (!inorecptr->ignore_alloc_blks) && (agg_recptr->treeQ_back == NULL)) { /* nothing fatal and tree looks ok and queue is empty */ xp_rc = xTree_node_last_in_level(xtiptr, inorecptr, msg_info_ptr, desired_action); } } release: /* * there's at least 1 more Q element to release for this node, and * if the tree is bad there may still be some on the queue as well. * * (If there's a processing error all the dynamic storage is going * to be released so there's no point in preparing these elements * for reuse.) */ if ((xp_rc == FSCK_OK) && (xtiptr->this_Qel != NULL)) { xp_rc = treeQ_rel_elem(xtiptr->this_Qel); } if ((xp_rc == FSCK_OK) && (xtiptr->next_Qel != NULL)) { xp_rc = treeQ_rel_elem(xtiptr->next_Qel); } agg_recptr->treeQ_back = NULL; while ((xp_rc == FSCK_OK) && (agg_recptr->treeQ_front != NULL)) { xtiptr->this_Qel = agg_recptr->treeQ_front; agg_recptr->treeQ_front = xtiptr->this_Qel->next; xp_rc = treeQ_rel_elem(xtiptr->this_Qel); } /* end while */ if (xp_rc == FSCK_OK) { /* not planning to quit */ if (desired_action != FSCK_RECORD_DUPCHECK) { /* we altered the corrupt tree bit */ if (old_ignore_alloc_blks && !inorecptr->ignore_alloc_blks) { /* * the flag is set but the bit didn't get * turned back on. This means that the first * time we went through this tree we decided * it was corrupt but this time it looked ok. */ xp_rc = FSCK_INTERNAL_ERROR_8; } else if (!old_ignore_alloc_blks && inorecptr->ignore_alloc_blks) { /* * the flag is off but the bit got turned on. * This means that the first time we went * through this tree it looked ok but this * time we decided that it is corrupt. */ xp_rc = FSCK_INTERNAL_ERROR_9; } } } out: return (xp_rc);}/***************************************************************************** * NAME: xTree_search * * FUNCTION: Search the xTree rooted in the given inode for an xad in a * leaf node which describes the given file offset. * * PARAMETERS: * inoptr - input - pointer to the inode in which the xTree is * rooted * given_key - input - the key (file offset) to match * addr_xad_ptr - input - pointer to a variable in which to return the * address of the xad whose key matches given_key * match_found - input - pointer to a variable in which to return * !0 if a matching xad is found * 0 if no match is found * * RETURNS: * success: FSCK_OK * failure: something else */int xTree_search(struct dinode *inoptr, int64_t given_key, xad_t ** addr_xad_ptr, int8_t * match_found){ int xs_rc = FSCK_OK; xtpage_t *xtpg_ptr; int8_t extent_located = 0; int8_t not_there = 0; int16_t chosen_idx; int8_t xad_chosen; int64_t last_offset; if (ISDIR(inoptr->di_mode)) xtpg_ptr = (xtpage_t *) & (inoptr->di_dirtable); else xtpg_ptr = (xtpage_t *) & (inoptr->di_btroot); while ((!extent_located) && (!not_there) && (xs_rc == FSCK_OK)) { if (given_key > offsetXAD(&xtpg_ptr->xad[xtpg_ptr->header.nextindex - 1])) { /* follows the start of the last allocation described */ chosen_idx = xtpg_ptr->header.nextindex - 1; xad_chosen = -1; } else if (given_key < offsetXAD(&(xtpg_ptr->xad[XTENTRYSTART]))) { /* precedes the 1st allocation described */ not_there = -1; xad_chosen = 0; } else { /* it's somewhere in between */ xs_rc = xTree_binsrch_page(xtpg_ptr, given_key, &xad_chosen, &chosen_idx, ¬_there); } if ((xs_rc == FSCK_OK) && (xad_chosen)) { /* picked one */ if (xtpg_ptr->header.flag & BT_LEAF) { /* it's this one or none */ /* the last offset in the extent described */ last_offset = offsetXAD(&(xtpg_ptr->xad[chosen_idx])) + lengthXAD(&(xtpg_ptr->xad[chosen_idx])) - 1; if (given_key <= last_offset) { /* it's in the range described */ extent_located = -1; } else { not_there = -1; } } else { /* this xad describes a B+ Tree node on the *next level down */ /* read in the next node */ xs_rc = node_get(addressXAD (&xtpg_ptr->xad[chosen_idx]), &xtpg_ptr); } } } if ((extent_located) && (xs_rc == FSCK_OK)) { /* found it! */ *addr_xad_ptr = &(xtpg_ptr->xad[chosen_idx]); *match_found = -1; } else { /* no luck */ *addr_xad_ptr = NULL; *match_found = 0; } return (xs_rc);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -