📄 fsckino.c
字号:
msg_info_ptr->msg_dxdtyp = fsck_objcontents; /* * Symbolic link is a special case. If the value fits within the * inode, the dxd appears to be an empty xtree, but it's unused. * In this case, ignore the dxd. */ if (ISLNK(inoptr->di_mode) && (inoptr->di_size < IDATASIZE)) { /* Null terminator stored but not accounted for in di_size */ agg_recptr->this_inode.in_inode_data_length = inoptr->di_size + 1; goto out; } /* * examine the data field */ if (dxd_ptr->flag == 0) goto out; if ((dxd_ptr->flag == (DXD_INDEX | BT_ROOT | BT_LEAF)) || (dxd_ptr->flag == (DXD_INDEX | BT_ROOT | BT_INTERNAL))) { /* * to be valid, it has to be a B-tree node, * either root-leaf or root-internal */ /* * figure out how much space the root occupies in the inode * itself */ xtp_ptr = (xtpage_t *) (&inoptr->di_btroot); agg_recptr->this_inode.in_inode_data_length = (xtp_ptr->header.maxentry - 2) * sizeof (xad_t); /* * the dxd actually starts 32 bytes (== 2 * length of * an xad) before the boundary. * the 0th and 1st entries in the xad array are * really the header */ /* * validate the tree contents and record the extents it * describes until and unless the tree is found to be corrupt */ vd_rc = xTree_processing(inoptr, inoidx, inorecptr, msg_info_ptr, FSCK_RECORD_DUPCHECK); if (vd_rc <= FSCK_OK) goto out; /* nothing fatal */ if (inorecptr->selected_to_rls && inode_is_metadata(inorecptr)) { vd_rc = FSCK_BADMDDATAIDX; } else if (inorecptr->ignore_alloc_blks) { /* the tree info can't be used */ if (inode_is_metadata(inorecptr)) { vd_rc = FSCK_BADMDDATAIDX; } /* * reverse the notations made when recording the * extents for the tree. Again, stop when the point * of corruption is found since that's where the * recording process was stopped. */ intermed_rc = xTree_processing(inoptr, inoidx, inorecptr, msg_info_ptr, FSCK_UNRECORD); if (intermed_rc < 0) { vd_rc = intermed_rc; goto out; } if (intermed_rc != FSCK_OK) { if (vd_rc == FSCK_OK) { vd_rc = intermed_rc; } } if (!inorecptr->ignore_ea_blks) { intermed_rc = backout_EA(inoptr, inorecptr); if (intermed_rc < 0) { vd_rc = intermed_rc; goto out; } if (intermed_rc != FSCK_OK) { if (vd_rc == FSCK_OK) { vd_rc = intermed_rc; } } if (!inorecptr->ignore_acl_blks) { intermed_rc = backout_ACL(inoptr, inorecptr); if (intermed_rc < 0) { vd_rc = intermed_rc; goto out; } if (intermed_rc != FSCK_OK) { if (vd_rc == FSCK_OK) { vd_rc = intermed_rc; } } } } } } else { /* else not B+ Tree index */ /* * the data root is not valid...the info cannot be trusted */ if (inode_is_metadata(inorecptr)) { vd_rc = FSCK_BADMDDATA; } else { inorecptr->selected_to_rls = 1; inorecptr->ignore_alloc_blks = 1; agg_recptr->corrections_needed = 1; } fsck_send_msg(fsck_BADINODXDFLDD, fsck_ref_msg(msg_info_ptr->msg_inotyp), fsck_ref_msg(msg_info_ptr->msg_inopfx), msg_info_ptr->msg_inonum, fsck_ref_msg(msg_info_ptr->msg_dxdtyp)); } out: return (vd_rc);}/***************************************************************************** * NAME: validate_dir_data * * FUNCTION: Determine whether the structures in, or rooted in, the * specified directory inode to describe data owned by the * inode are consistent and (as far as fsck can tell) * correct. * * PARAMETERS: * inoptr - input - pointer to the current inode * inoidx - input - ordinal number of the inode as an integer * inorecptr - input - pointer to an fsck inode record describing the * current inode * msg_info_ptr - input - pointer to a record with information needed * to issue messages about the current inode * * RETURNS: * success: FSCK_OK * failure: something else */int validate_dir_data(struct dinode *inoptr, uint32_t inoidx, struct fsck_inode_record *inorecptr, struct fsck_ino_msg_info *msg_info_ptr){ int vdd_rc = FSCK_OK; int intermed_rc = FSCK_OK; int dtree_rc = FSCK_OK; dxd_t *dxd_ptr; int8_t save_ignore_alloc_blks; int8_t xt_ignore_alloc_blks = 0; dxd_ptr = &(inoptr->di_dxd); /* the data root dxd */ msg_info_ptr->msg_dxdtyp = fsck_objcontents; /* * examine the data field */ if (dxd_ptr->flag == 0) goto out; /* Work around bug that used to clear the DXD_INDEX bit */ dxd_ptr->flag |= DXD_INDEX; /* * to be valid, it has to be a B-tree node, * either root-leaf or root-internal */ if ((dxd_ptr->flag != (DXD_INDEX | BT_ROOT | BT_LEAF)) && (dxd_ptr->flag != (DXD_INDEX | BT_ROOT | BT_INTERNAL))) { /* * the data root is not valid...the info cannot be trusted */ inorecptr->selected_to_rls = 1; inorecptr->ignore_alloc_blks = 1; agg_recptr->corrections_needed = 1; fsck_send_msg(fsck_BADINODXDFLDD, fsck_ref_msg(msg_info_ptr->msg_inotyp), fsck_ref_msg(msg_info_ptr->msg_inopfx), msg_info_ptr->msg_inonum, fsck_ref_msg(msg_info_ptr->msg_dxdtyp)); goto out; } /* * figure out how much space the root occupies in the inode itself */ agg_recptr->this_inode.in_inode_data_length = (DTROOTMAXSLOT - 1) * sizeof (struct dtslot); /* * The root actually starts 32 bytes (aka the length * of 1 slot) before the boundary. * the 1st slot is really the header */ /* * process the xtree if the new directory table is supported * and if the directory table data is not inline (index > 14) */ if (sb_ptr->s_flag & JFS_DIR_INDEX) inorecptr->check_dir_index = 1; if ((sb_ptr->s_flag & JFS_DIR_INDEX) && inoptr->di_next_index > MAX_INLINE_DIRTABLE_ENTRY + 1) { /* * validate the tree contents and record the extents it * describes until and unless the tree is found to be corrupt */ vdd_rc = xTree_processing(inoptr, inoidx, inorecptr, msg_info_ptr, FSCK_RECORD_DUPCHECK); if (vdd_rc < FSCK_OK) goto out; } /* * Check an error bit to see if there was something * wrong but non-fatal with xTree_processing. If * so, reset the bit to give dTree_processing a * clean slate to start with. Set a flag to * indicate that the directory index table is to be rebuilt. */ if (inorecptr->ignore_alloc_blks) { inorecptr->check_dir_index = 0; inorecptr->rebuild_dirtable = 1; inorecptr->ignore_alloc_blks = 0; inorecptr->selected_to_rls = 0; agg_recptr->corrections_needed = 1; xt_ignore_alloc_blks = 1; } /* * validate the tree contents and record the extents it * describes until and unless the tree is found to be corrupt */ dtree_rc = dTree_processing(inoptr, inoidx, inorecptr, msg_info_ptr, FSCK_RECORD_DUPCHECK); if (dtree_rc < FSCK_OK) goto dtree_out; if (inorecptr->ignore_alloc_blks) { /* the tree info can't be used */ /* * reverse the notations made when recording the extents * for the tree. Again, stop when the point of corruption * is found since that's where the recording process was * stopped. */ intermed_rc = dTree_processing(inoptr, inoidx, inorecptr, msg_info_ptr, FSCK_UNRECORD); if (intermed_rc < 0) { dtree_rc = intermed_rc; goto dtree_out; } if (intermed_rc != FSCK_OK) { if (dtree_rc == FSCK_OK) { dtree_rc = intermed_rc; } } if (!inorecptr->ignore_ea_blks) { intermed_rc = backout_EA(inoptr, inorecptr); if (intermed_rc < 0) { dtree_rc = intermed_rc; goto dtree_out; } if (intermed_rc != FSCK_OK) { if (dtree_rc == FSCK_OK) { dtree_rc = intermed_rc; } } if (!inorecptr->ignore_acl_blks) { intermed_rc = backout_ACL(inoptr, inorecptr); if (intermed_rc < 0) { dtree_rc = intermed_rc; goto dtree_out; } if (intermed_rc != FSCK_OK) { if (dtree_rc == FSCK_OK) { dtree_rc = intermed_rc; } } } } } if ((sb_ptr->s_flag & JFS_DIR_INDEX) && (inoptr->di_next_index > MAX_INLINE_DIRTABLE_ENTRY + 1) && (inorecptr->ignore_alloc_blks || inorecptr->rebuild_dirtable)) { /* * ignore_alloc_blks needs to exactly reflect the results * of the xTree_processing step */ save_ignore_alloc_blks = inorecptr->ignore_alloc_blks; inorecptr->ignore_alloc_blks = xt_ignore_alloc_blks; /* * reverse the notations made when recording the * extents for the tree. Again, stop when the point * of corruption is found since that's where the * recording process was stopped. */ intermed_rc = xTree_processing(inoptr, inoidx, inorecptr, msg_info_ptr, FSCK_UNRECORD); if (intermed_rc < 0) { vdd_rc = intermed_rc; goto out; } if (intermed_rc != FSCK_OK) { if (vdd_rc == FSCK_OK) { vdd_rc = intermed_rc; } } inorecptr->ignore_alloc_blks = save_ignore_alloc_blks; /* * If we don't fix di_nblocks now, the inode will be * thrown away (even if dtree is good). */ inoptr->di_nblocks = agg_recptr->this_inode.all_blks; } dtree_out: /* * return the worse of the rc's for xtree and dtree processing */ if (dtree_rc != FSCK_OK) { vdd_rc = dtree_rc; } out: return (vdd_rc);}/***************************************************************************** * NAME: validate_EA * * FUNCTION: Determine whether the structures in the specified inode to * describe ea data owned by the inode are consistent and (as * far as fsck can tell) correct. * * PARAMETERS: * inoptr - input - pointer to the current inode * inoidx - input - ordinal number of the inode as an integer * inorecptr - input - pointer to an fsck inode record describing * the current inode * msg_info_ptr - input - pointer to a record with information needed * to issue messages about the current inode * * RETURNS: * success: FSCK_OK * failure: something else */int validate_EA(struct dinode *inoptr, uint32_t inoidx, struct fsck_inode_record *inorecptr, struct fsck_ino_msg_info *msg_info_ptr){ int vea_rc = FSCK_OK; int intermed_rc = FSCK_OK; dxd_t *dxd_ptr; uint32_t recorded_length, shortest_valid, longest_valid; uint32_t ext_length; int64_t ext_byte_length; int64_t ext_address = 0; int8_t extent_is_valid = 0; int8_t ea_format_bad = 0; uint16_t size16; struct dinode an_inode; unsigned long eafmt_error = 0; dxd_ptr = &(inoptr->di_ea); msg_info_ptr->msg_dxdtyp = fsck_EA; if (dxd_ptr->flag == 0) goto out; /* there is an EA for this inode */ if ((dxd_ptr->flag != DXD_EXTENT) && (dxd_ptr->flag != DXD_INLINE)) { /* not a single extent AND not inline */ fsck_send_msg(fsck_BADINODXDFLDD, fsck_ref_msg(msg_info_ptr->msg_inotyp), fsck_ref_msg(msg_info_ptr->msg_inopfx), msg_info_ptr->msg_inonum, fsck_ref_msg(msg_info_ptr->msg_dxdtyp)); inorecptr->clr_ea_fld = 1; inorecptr->ignore_ea_blks = 1; agg_recptr->corrections_needed = 1; goto out; } if (dxd_ptr->flag == DXD_INLINE) { /* EA is inline */ size16 = sizeof (an_inode.di_inlineea); agg_recptr->this_inode.ea_inline = 1; agg_recptr->this_inode.inline_ea_length = dxd_ptr->size; agg_recptr->this_inode.inline_ea_offset = (uint16_t) addressDXD(dxd_ptr); if ((dxd_ptr->size == 0) || (dxd_ptr->size > (size16 - agg_recptr->this_inode.inline_ea_offset))) { /* * the length extends * beyond the end of the inode */ fsck_send_msg(fsck_BADINODXDFLDL, fsck_ref_msg(msg_info_ptr->msg_inotyp), fsck_ref_msg(msg_info_ptr->msg_inopfx), msg_info_ptr->msg_inonum, fsck_ref_msg(msg_info_ptr->msg_dxdtyp)); inorecptr->clr_ea_fld = 1; agg_recptr->corrections_needed = 1; } else { /* the inline ea has a valid length. * verify its format. */ vea_rc = jfs_ValidateFEAList((struct FEALIST *) &(inoptr->di_inlineea), dxd_ptr->size, &eafmt_error); if ((vea_rc != FSCK_OK) || (eafmt_error != 0)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -