📄 fsckimap.c
字号:
if (!source_is_primary) { /* we're trying to repair the primary * table and can't -- that makes this a * dirty file system. */ agg_recptr->ag_dirty = 1; fsck_send_msg(fsck_CANTREPAIRAIS, "1"); } else { /* trying to repair the secondary table and can't * * We won't stop fsck and we won't mark the file system * dirty on this condition, but we'll issue a warning * and mark the superblock to prevent future attempts * to maintain the flawed table. */ *replication_failure = -1; fsck_send_msg(fsck_INCONSIST2NDRY1, "1"); } }aimr_exit: return (aimr_rc);}/**************************************************************** * NAME: AIS_inode_check * * FUNCTION: Compare the specified Primary Inode Allocation Table inode * to its (specified) Secondary Inode Allocation Table 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 * tree_offset - input - the offset of the B+ Tree rooted * in the inode * tree_size - input - the number of inodes bytes occupied * by the B+ tree rooted in the inode * 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 AIS_inode_check(struct dinode *primary_inoptr, struct dinode *secondary_inoptr, int32_t tree_offset, int32_t tree_size, int *inconsistency_detected){ xtpage_t *primary_root, *secondary_root; int32_t result1, result2, result3, result4, result5, result6; *inconsistency_detected = ((primary_inoptr->di_inostamp != secondary_inoptr->di_inostamp) || (primary_inoptr->di_fileset != secondary_inoptr->di_fileset) || (primary_inoptr->di_number != secondary_inoptr->di_number) || (primary_inoptr->di_gen != secondary_inoptr->di_gen) || (primary_inoptr->di_size != secondary_inoptr->di_size) || (primary_inoptr->di_nblocks != secondary_inoptr->di_nblocks) || (primary_inoptr->di_nlink != secondary_inoptr->di_nlink) || (primary_inoptr->di_uid != secondary_inoptr->di_uid) || (primary_inoptr->di_gid != secondary_inoptr->di_gid) || (primary_inoptr->di_mode != secondary_inoptr->di_mode) || (primary_inoptr->di_next_index != secondary_inoptr->di_next_index)); if (!(*inconsistency_detected)) { if (tree_offset == 0) { result1 = 0; } else { /* tree compare needed */ primary_root = (xtpage_t *) (((char *) primary_inoptr) + tree_offset); secondary_root = (xtpage_t *) (((char *) primary_inoptr) + tree_offset); result1 = memcmp((void *) primary_root, (void *) secondary_root, tree_size); } result2 = memcmp((void *) &(primary_inoptr->di_atime), (void *) &(secondary_inoptr->di_atime), sizeof (primary_inoptr->di_atime)); result3 = memcmp((void *) &(primary_inoptr->di_ctime), (void *) &(secondary_inoptr->di_ctime), sizeof (primary_inoptr->di_ctime)); result4 = memcmp((void *) &(primary_inoptr->di_mtime), (void *) &(secondary_inoptr->di_mtime), sizeof (primary_inoptr->di_mtime)); result5 = memcmp((void *) &(primary_inoptr->di_otime), (void *) &(secondary_inoptr->di_otime), sizeof (primary_inoptr->di_otime)); result6 = memcmp((void *) &(primary_inoptr->di_ea), (void *) &(secondary_inoptr->di_ea), sizeof (primary_inoptr->di_ea)); *inconsistency_detected = (result1 || result2 || result3 || result4 || result5 || result6); } if (!(*inconsistency_detected)) { *inconsistency_detected = memcmp((void *) &(sb_ptr->s_ait2), (void *) &(secondary_inoptr-> di_ixpxd), sizeof (pxd_t)); } if ((*inconsistency_detected)) { /* future recover 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, "2"); } return (FSCK_OK);}/**************************************************************** * NAME: AIS_inode_replication * * FUNCTION: Rebuild the specified target inode by making it the logical * equivalent of the specified source inode. * * PARAMETERS: * source_is_primary - input - !0 => replicate from primary to secondary * 0 => replicate from secondary to primary * target_inoptr - input - address of an inode in the aggregate * inode allocation table (primary or * secondary) which is the target of the * replication * source_inoptr - input - address of the equivalent inode in the * aggregate inode allocation table (secondary * or primary) which is the source of the * secondary) which is the target of the * replication * * NOTES: o The caller to this routine must ensure that the first extent * of the primary aggregate inode allocation table is at the * beginning of the fsck temporary inode buffer and that the * first extent of the secondary aggregate inode allocation map * immediately follows it in the fsck temporary inode buffer. * * RETURNS: * success: FSCK_OK * failure: something else */int AIS_inode_replication(int8_t source_is_primary, struct dinode *target_inoptr, struct dinode *source_inoptr){ int aisir_rc = FSCK_OK; int64_t ext_offset; /* * copy the source over the target, then adjust the field(s) which * should be different. */ memcpy((void *) target_inoptr, (void *) source_inoptr, sizeof (struct dinode)); if (source_is_primary) { memcpy((void *) &(target_inoptr->di_ixpxd), (void *) &(sb_ptr->s_ait2), sizeof (pxd_t)); } else { ext_offset = AITBL_OFF / sb_ptr->s_bsize; PXDaddress(&(target_inoptr->di_ixpxd), ext_offset); PXDlength(&(target_inoptr->di_ixpxd), lengthPXD(&sb_ptr->s_ait2)); } return (aisir_rc);}/**************************************************************** * NAME: AIS_redundancy_check * * FUNCTION: Verify that the Secondary Aggregate Inode structures are * logically equivalent to the Primary Aggregate Inode structures. * * PARAMETERS: none * * NOTES: o The "aggregate inode structures" are the Aggregate Inode Map * and the Aggregate Inode Table. * * o This routine reads the first extent of the Primary Aggregate * Inode Table into the first page of the fsck temporary inode * buffer and reads the first extent of the Secondary Aggregate * Inode table into the regular fsck inode buffer. * * RETURNS: * success: FSCK_OK * failure: something else */int AIS_redundancy_check(){ int aisrc_rc = FSCK_OK; struct dinode *primary_inoptr, *secondary_inoptr; xtpage_t *secondary_ait_root = NULL; char *primary_bufptr, *secondary_bufptr; int32_t inode_offset; int inconsistency_detected = 0; int32_t tree_offset, treesize; struct fsck_inode_record temp_inorec; struct fsck_inode_record *temp_inorecptr = &temp_inorec; struct fsck_ino_msg_info temp_msg_info; struct fsck_ino_msg_info *temp_msg_infoptr = &temp_msg_info; aisrc_rc = temp_inode_buf_alloc(&primary_bufptr); if (aisrc_rc != FSCK_OK) goto aisrc_exit; secondary_bufptr = agg_recptr->ino_buf_ptr; tree_offset = (int32_t) &(((struct dinode *)0)->di_btroot); treesize = sizeof (primary_inoptr->di_DASD) + sizeof (primary_inoptr->di_dxd) + sizeof (primary_inoptr->di_inlinedata); /* allocated the temp buffer */ aisrc_rc = ait_special_read_ext1(fsck_primary); if (aisrc_rc != FSCK_OK) { /* read failed */ report_readait_error(aisrc_rc, FSCK_FAILED_CANTREADAITEXT1, fsck_primary); aisrc_rc = FSCK_FAILED_CANTREADAITEXT1; goto aisrc_exit; } /* primary is in the inode buffer */ memcpy((void *) primary_bufptr, (void *) agg_recptr->ino_buf_ptr, INODE_IO_BUFSIZE); aisrc_rc = ait_special_read_ext1(fsck_secondary); if (aisrc_rc != FSCK_OK) { /* read failed */ report_readait_error(aisrc_rc, FSCK_FAILED_CANTREADAITEXT2, fsck_secondary); aisrc_rc = FSCK_FAILED_CANTREADAITEXT2; goto aisrc_exit; } /* the 2 inode extents are in memory */ /* * the self inode */ inode_offset = AGGREGATE_I * sizeof (struct dinode); primary_inoptr = (struct dinode *) (primary_bufptr + inode_offset); secondary_inoptr = (struct dinode *) (secondary_bufptr + inode_offset); aisrc_rc = AIS_inode_check(primary_inoptr, secondary_inoptr, 0, 0, &inconsistency_detected); if ((aisrc_rc != FSCK_OK) || inconsistency_detected) goto aisrc_exit; secondary_ait_root = (xtpage_t *) & (secondary_inoptr->di_btroot); /* * the block map inode */ inode_offset = BMAP_I * sizeof (struct dinode); primary_inoptr = (struct dinode *) (primary_bufptr + inode_offset); secondary_inoptr = (struct dinode *) (secondary_bufptr + inode_offset); aisrc_rc = AIS_inode_check(primary_inoptr, secondary_inoptr, tree_offset, treesize, &inconsistency_detected); if ((aisrc_rc != FSCK_OK) || inconsistency_detected) goto aisrc_exit; /* * the journal log inode */ inode_offset = LOG_I * sizeof (struct dinode); primary_inoptr = (struct dinode *) (primary_bufptr + inode_offset); secondary_inoptr = (struct dinode *) (secondary_bufptr + inode_offset); aisrc_rc = AIS_inode_check(primary_inoptr, secondary_inoptr, tree_offset, treesize, &inconsistency_detected); if ((aisrc_rc != FSCK_OK) || inconsistency_detected) goto aisrc_exit; /* * the bad block inode */ inode_offset = BADBLOCK_I * sizeof (struct dinode); primary_inoptr = (struct dinode *) (primary_bufptr + inode_offset); secondary_inoptr = (struct dinode *) (secondary_bufptr + inode_offset); aisrc_rc = AIS_inode_check(primary_inoptr, secondary_inoptr, tree_offset, treesize, &inconsistency_detected); if ((aisrc_rc != FSCK_OK) || inconsistency_detected) goto aisrc_exit; /* and finally the filesystem inode */ inode_offset = FILESYSTEM_I * sizeof (struct dinode); primary_inoptr = (struct dinode *) (primary_bufptr + inode_offset); secondary_inoptr = (struct dinode *) (secondary_bufptr + inode_offset); aisrc_rc = AIS_inode_check(primary_inoptr, secondary_inoptr, 0, 0, &inconsistency_detected); if ((aisrc_rc != FSCK_OK) || inconsistency_detected) goto aisrc_exit; temp_inorecptr->inonum = FILESYSTEM_I; temp_inorecptr->in_use = 0; temp_inorecptr->selected_to_rls = 0; temp_inorecptr->crrct_link_count = 0; temp_inorecptr->crrct_prnt_inonum = 0; temp_inorecptr->adj_entries = 0; temp_inorecptr->cant_chkea = 0; temp_inorecptr->clr_ea_fld = 0; temp_inorecptr->clr_acl_fld = 0; temp_inorecptr->inlineea_on = 0; temp_inorecptr->inlineea_off = 0; temp_inorecptr->inline_data_err = 0; temp_inorecptr->ignore_alloc_blks = 0; temp_inorecptr->reconnect = 0; temp_inorecptr->unxpctd_prnts = 0; temp_inorecptr->badblk_inode = 0; temp_inorecptr->involved_in_dups = 0; temp_inorecptr->inode_type = metadata_inode; temp_inorecptr->link_count = 0; temp_inorecptr->parent_inonum = 0; temp_inorecptr->ext_rec = NULL; temp_msg_infoptr->msg_inonum = FILESYSTEM_I; temp_msg_infoptr->msg_inopfx = fsck_aggr_inode; temp_msg_infoptr->msg_inotyp = fsck_metadata; temp_msg_infoptr->msg_dxdtyp = 0; /* * need to verify the tree structure in the secondary * aggregate fileset inode and record/dupcheck the * tree nodes (but not the data extents described by * the leaf node(s)). */ aisrc_rc = xTree_processing(secondary_inoptr, FILESYSTEM_I, temp_inorecptr, temp_msg_infoptr, FSCK_FSIM_RECORD_DUPCHECK); if (temp_inorecptr->involved_in_dups || temp_inorecptr->selected_to_rls || temp_inorecptr->ignore_alloc_blks) { inconsistency_detected = -1; aisrc_rc = xTree_processing(secondary_inoptr, FILESYSTEM_I, temp_inorecptr, temp_msg_infoptr, FSCK_FSIM_UNRECORD); /* * 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, "4"); } else { /* the tree is good and its nodes have been recorded */ aisrc_rc = FSIM_check(primary_inoptr, secondary_inoptr, &inconsistency_detected); } if ((aisrc_rc != FSCK_OK) || inconsistency_detected) goto aisrc_exit; /* * no problems detected in the AIT -- * now verify the secondary AIM */ aisrc_rc = AIM_check(secondary_ait_root, primary_bufptr, &inconsistency_detected);aisrc_exit: temp_inode_buf_release(primary_bufptr); return (aisrc_rc);}/**************************************************************** * NAME: AIS_replication * * FUNCTION: Rebuild the aggregate inode structures so that the Secondary * Aggregate Inode structures are logically equivalent to the * Primary Aggregate Inode structures. * * PARAMETERS: none * * NOTES: o Since the roles of source and target AIT can change * during this routine, we read both source and target * so that when we write we preserve the portion of the * target extent which is really a source. * (This is simpler than attempting to write individual * inodes and dealing with the question of device block * size larger than an inode.) * * o The "aggregate inode structures" are the Aggregate Inode Map * and the Aggregate Inode Table. * * o This routine reads the first extent of one Aggregate Inode * Table into the fsck temporary inode buffer and reads the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -