📄 fsckimap.c
字号:
which_it = fsck_primary; else which_it = fsck_secondary; rdie_rc = get_inorecptr(is_aggregate, 0, AGGREGATE_I, &inorecptr); if ((rdie_rc == FSCK_OK) && (inorecptr == NULL)) rdie_rc = FSCK_INTERNAL_ERROR_18; if (rdie_rc != FSCK_OK) goto rdie_exit; rdie_rc = first_refchk_inoexts(is_aggregate, which_it, inorecptr, msg_info_ptr); if (rdie_rc != FSCK_OK) goto rdie_exit; /* * check the inode extents in the Fileset Inode Allocation Maps * for first references to multiply allocated blocks. * * (In release 1 there is exactly 1 fileset) */ which_it = FILESYSTEM_I; /* aggregate inode */ is_aggregate = -1; rdie_rc = get_inorecptr(is_aggregate, 0, FILESYSTEM_I, &inorecptr); if ((rdie_rc == FSCK_OK) && (inorecptr == NULL)) rdie_rc = FSCK_INTERNAL_ERROR_19; if (rdie_rc != FSCK_OK) goto rdie_exit; /* fileset IAGs */ is_aggregate = 0; rdie_rc = first_refchk_inoexts(is_aggregate, which_it, inorecptr, msg_info_ptr);rdie_exit: return (rdie_rc);}/**************************************************************** * NAME: first_refchk_inoexts * * FUNCTION: Check all inode extents described by IAGs in the specified * inode table to determine whether they contain a reference * to any multiply-allocated aggregate block whose first reference * has not yet been resolved. * * PARAMETERS: * is_aggregate - input - !0 => aggregate owned * 0 => fileset owned * which_it - input - ordinal number of the aggregate inode * describing the inode table * inorecptr - input - pointer to an fsck inode record which * describes the current inode allocation * table inode * msg_info_ptr - input - pointer to data needed to issue messages * about the current inode * * NOTES: o Since this routine completes the fsck workspace * initialization needed by inode_get() (et al), this * routine ensures fsck I/O buffers contain the inode * it needs before invoking inode_get(). * (inode_get() is invoked to locate the inode within * the fsck I/O buffer.) * * RETURNS: * success: FSCK_OK * failure: something else */int first_refchk_inoexts(int is_aggregate, int which_it, struct fsck_inode_record *inorecptr, struct fsck_ino_msg_info *msg_info_ptr){ int ifrie_rc = FSCK_OK; struct iag *iagptr; uint32_t ext_idx; uint32_t ext_idx_max; int64_t ext_addr; uint32_t ext_len; int which_ait; int8_t is_EA = 0; int8_t is_ACL = 0; int8_t extent_is_valid; uint32_t adjusted_length; ext_idx_max = EXTSPERIAG - 1; if (is_aggregate) { if (agg_recptr->primary_ait_4part1) { which_ait = fsck_primary; } else { which_ait = fsck_secondary; } } else { if (agg_recptr->primary_ait_4part2) { which_ait = fsck_primary; } else { which_ait = fsck_secondary; } } ifrie_rc = iag_get_first(is_aggregate, which_it, which_ait, &iagptr); while ((iagptr != NULL) && (agg_recptr->unresolved_1stref_count > 0) && (ifrie_rc == FSCK_OK)) { for (ext_idx = 0; ((ext_idx <= ext_idx_max) && (agg_recptr->unresolved_1stref_count > 0) && (ifrie_rc == FSCK_OK)); ext_idx++) { ext_addr = addressPXD(&(iagptr->inoext[ext_idx])); if (ext_addr != 0) { /* the extent is allocated */ ext_len = lengthPXD(&(iagptr->inoext[ext_idx])); ifrie_rc = process_extent(inorecptr, ext_len, ext_addr, is_EA, is_ACL, msg_info_ptr, &adjusted_length, &extent_is_valid, FSCK_QUERY); } } if (ifrie_rc == FSCK_OK) { ifrie_rc = iag_get_next(&iagptr); } } return (ifrie_rc);}/*-------------------------------------------------------------------- * NAME: FSIM_add_extents * * FUNCTION: Add an extent of <thisblk> to the <bb_inode> inode * * NOTES: * o It is not necessary to mark the extent in the block map * since it is an extent already owned by the source * FileSet Inode Map. * * PARAMETERS: * thisblk - block number of bad block to add * bb_inode - Inode to add bad block to * * RETURNS: 0 for success; Other indicates failure */int FSIM_add_extents(xtpage_t * src_leaf_ptr, struct dinode *target_inode, int8_t * replication_failed){ int fsimae_rc = FSCK_OK; int32_t xad_idx, ext_length, ext_bytes; int64_t ext_addr; *replication_failed = 0; for (xad_idx = XTENTRYSTART; ((fsimae_rc == FSCK_OK) && (!*replication_failed) && (xad_idx < src_leaf_ptr->header.nextindex)); xad_idx++) { ext_addr = addressXAD(&(src_leaf_ptr->xad[xad_idx])); ext_length = lengthXAD(&(src_leaf_ptr->xad[xad_idx])); ext_bytes = ext_length << agg_recptr->log2_blksize; fsimae_rc = xtAppend(target_inode, target_inode->di_size / sb_ptr->s_bsize, ext_addr, ext_length, fsim_node_pages); target_inode->di_size += ext_bytes; target_inode->di_nblocks += ext_length; } if (fsimae_rc > 0) { /* an error, but not fatal */ *replication_failed = -1; fsimae_rc = FSCK_OK; } return (fsimae_rc);}/**************************************************************** * NAME: FSIM_check * * FUNCTION: Compare the specified Primary Fileset Inode Map to its * (specified) Secondary Fileset Inode Map counterpart to * ensure that they are logically equivalent. * * PARAMETERS: * primary_inoptr - input - pointer to an inode in the primary * aggregate inode allocation table * in an fsck buffer * secondary_inoptr - input - pointer to the equivalent inode in * the secondary aggregate inode * allocation table in an fsck buffer * inconsistency_detected - input - pointer to a variable in which * to return !0 if errors are detected * 0 if no errors are detected * * RETURNS: * success: FSCK_OK * failure: something else */int FSIM_check(struct dinode *primary_inoptr, struct dinode *secondary_inoptr, int *inconsistency_detected){ int fsimc_rc = FSCK_OK; xtpage_t *primary_nodeptr, *secondary_nodeptr, *leaf_node; int8_t primary_is_inline, primary_is_rootleaf; int8_t secondary_is_inline, secondary_is_rootleaf; int leaf_length; int64_t node_agg_offset; /* * allocate 2 buffers to contain the node */ fsimc_rc = temp_node_buf_alloc((char **) (&agg_recptr->prim_nodeptr)); if (fsimc_rc != FSCK_OK) goto fsimc_set_exit; /* first node buffer allocated */ primary_nodeptr = agg_recptr->prim_nodeptr; fsimc_rc = temp_node_buf_alloc((char **) (&agg_recptr->second_nodeptr)); if (fsimc_rc != FSCK_OK) goto fsimc_set_exit; /* second node buffer allocated */ secondary_nodeptr = agg_recptr->second_nodeptr; fsimc_rc = find_first_leaf(primary_inoptr, &leaf_node, &node_agg_offset, &primary_is_inline, &primary_is_rootleaf); if (fsimc_rc != FSCK_OK) { *inconsistency_detected = -1; fsimc_rc = FSCK_OK; goto fsimc_set_exit; } /* got first leaf of primary fs inode map * * copy it into the temp primary node buffer */ if (primary_is_rootleaf) { leaf_length = XTROOTMAXSLOT * sizeof (xad_t); memcpy((void *) primary_nodeptr, (void *) &(primary_inoptr->di_btroot), leaf_length); } else { leaf_length = XTPAGE_SIZE; memcpy((void *) primary_nodeptr, (void *) leaf_node, leaf_length); } fsimc_rc = find_first_leaf(secondary_inoptr, &leaf_node, &node_agg_offset, &secondary_is_inline, &secondary_is_rootleaf); if (fsimc_rc != FSCK_OK) { *inconsistency_detected = -1; fsimc_rc = FSCK_OK; goto fsimc_set_exit; } /* got first leaf of secondary fs inode map * * copy it into the temp secondary node buffer */ if (secondary_is_rootleaf) { leaf_length = XTROOTMAXSLOT * sizeof (xad_t); memcpy((void *) secondary_nodeptr, (void *) &(secondary_inoptr->di_btroot), leaf_length); } else { leaf_length = XTPAGE_SIZE; memcpy((void *) secondary_nodeptr, (void *) leaf_node, leaf_length); } if (*inconsistency_detected) goto fsimc_set_exit; if ((primary_is_rootleaf != secondary_is_rootleaf) || (primary_is_inline != secondary_is_inline)) { *inconsistency_detected = -1; goto fsimc_set_exit; } /* either both or neither is a rootleaf */ if (primary_is_rootleaf) { /* they're root leaf nodes */ fsimc_rc = IM_compare_leaf(primary_nodeptr, secondary_nodeptr, inconsistency_detected); goto fsimc_set_exit; } /* they're not root leaf nodes */ while ((primary_nodeptr != NULL) && (secondary_nodeptr != NULL)) { fsimc_rc = IM_compare_leaf(primary_nodeptr, secondary_nodeptr, inconsistency_detected); if ((fsimc_rc != FSCK_OK) || *inconsistency_detected) break; /* leafs compare as equal */ if (primary_nodeptr->header.next == 0) primary_nodeptr = NULL; else { /* primary leaf has a next */ node_agg_offset = primary_nodeptr->header.next; fsimc_rc = ait_node_get(node_agg_offset, primary_nodeptr); if (fsimc_rc != FSCK_OK) { if (fsimc_rc > 0) { /* error but not fatal */ *inconsistency_detected = -1; fsimc_rc = FSCK_OK; } break; } } if (secondary_nodeptr->header.next == 0) secondary_nodeptr = NULL; else { /* secondary leaf has a next */ node_agg_offset = secondary_nodeptr->header.next; fsimc_rc = ait_node_get(node_agg_offset, secondary_nodeptr); if (fsimc_rc != FSCK_OK) { if (fsimc_rc > 0) { /* error but not fatal */ *inconsistency_detected = -1; fsimc_rc = FSCK_OK; } break; } } } if ((primary_nodeptr != NULL) || (secondary_nodeptr != NULL)) /* on exit these should both be NULL */ *inconsistency_detected = -1; fsimc_set_exit: if ((*inconsistency_detected)) { /* future recovery capability is compromised * * Note that we're in read-only mode or we wouldn't be checking * this (because when we have write access we always rebuild it */ fsck_send_msg(fsck_INCONSIST2NDRY, "3"); } return (fsimc_rc);}/**************************************************************** * NAME: FSIM_replication * * FUNCTION: Replicate the Fileset Inode Map from the given source Aggregate * Map to the given target Aggregate Inode Map so that they are * logically equivalent. That is, so that they have independent * B+Trees, but the leaf level of the 2 trees point to the same "data" * extents (control page and IAGs). * * PARAMETERS: * source_is_primary - input - 0 if secondary FSIM is being replicated * into primary FSIM * !0 if primary FSIM is being replicated into * secondary FSIM * source_inoptr - input - pointer to an inode in the primary * aggregate inode allocation table in an fsck * buffer * target_inoptr - input - pointer to the equivalent inode in the * secondary aggregate inode allocation table in * an fsck buffer * replication_failed - input - ptr to a variable in which to return 0 * if the FSIM is successfully replicated and * !0 if the FSIM is not successfully * replicated * * RETURNS: * success: FSCK_OK * failure: something else */int FSIM_replication(int8_t source_is_primary, struct dinode *target_inoptr, struct dinode *source_inoptr, int8_t * replication_failed){ int fsimr_rc = FSCK_OK; xtpage_t *source_nodeptr, *leaf_node; int8_t source_is_inline, source_is_rootleaf; int leaf_length = 0; int64_t node_agg_offset; struct xtree_buf *curpage; int I_am_logredo = 0; /* * allocate a buffer to contain the source leaf nodes */ fsimr_rc = temp_node_buf_alloc((char **) (&agg_recptr->prim_nodeptr)); if (fsimr_rc != FSCK_OK) goto fsimr_exit; /* node buffer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -