📄 fsckmeta.c
字号:
inorecptr->link_count = 0; inorecptr->parent_inonum = 0; inorecptr->ext_rec = NULL; raitp1a_rc = record_valid_inode(ino_ptr, ino_idx, inorecptr, msg_info_ptr); } if (raitp1a_rc == FSCK_OK) { /* recorded it successfully */ inorecptr->in_use = 1; } } if (raitp1a_rc == FSCK_OK) { /* self inode recorded ok */ /* try for the blockmap inode */ ino_idx = BMAP_I; msg_info_ptr->msg_inonum = ino_idx; raitp1a_rc = inode_get(aggregate_inode, which_ait, ino_idx, &ino_ptr); if (raitp1a_rc == FSCK_OK) { /* got the block map inode */ raitp1a_rc = get_inorecptr(aggregate_inode, alloc_ifnull, ino_idx, &inorecptr); if ((raitp1a_rc == FSCK_OK) && (inorecptr == NULL)) { raitp1a_rc = FSCK_INTERNAL_ERROR_43; fsck_send_msg(fsck_INTERNALERROR, raitp1a_rc, 0, 0, 0); } else if (raitp1a_rc == FSCK_OK) { inorecptr->in_use = 0; inorecptr->selected_to_rls = 0; inorecptr->crrct_link_count = 0; inorecptr->crrct_prnt_inonum = 0; inorecptr->adj_entries = 0; inorecptr->cant_chkea = 0; inorecptr->clr_ea_fld = 0; inorecptr->clr_acl_fld = 0; inorecptr->inlineea_on = 0; inorecptr->inlineea_off = 0; inorecptr->inline_data_err = 0; inorecptr->ignore_alloc_blks = 0; inorecptr->reconnect = 0; inorecptr->unxpctd_prnts = 0; inorecptr->badblk_inode = 0; inorecptr->involved_in_dups = 0; inorecptr->inode_type = metadata_inode; inorecptr->link_count = 0; inorecptr->parent_inonum = 0; inorecptr->ext_rec = NULL; raitp1a_rc = record_valid_inode(ino_ptr, ino_idx, inorecptr, msg_info_ptr); } if (raitp1a_rc == FSCK_OK) { /* recorded it successfully */ inorecptr->in_use = 1; } } } if (raitp1a_rc == FSCK_OK) { /* self and bmap inodes recorded ok */ /* try for the journal log inode */ ino_idx = LOG_I; msg_info_ptr->msg_inonum = ino_idx; raitp1a_rc = inode_get(aggregate_inode, which_ait, ino_idx, &ino_ptr); if (raitp1a_rc == FSCK_OK) { /* got the journal log inode */ raitp1a_rc = get_inorecptr(aggregate_inode, alloc_ifnull, ino_idx, &inorecptr); if ((raitp1a_rc == FSCK_OK) && (inorecptr == NULL)) { raitp1a_rc = FSCK_INTERNAL_ERROR_44; fsck_send_msg(fsck_INTERNALERROR, raitp1a_rc, 0, 0, 0); } else if (raitp1a_rc == FSCK_OK) { inorecptr->in_use = 0; inorecptr->selected_to_rls = 0; inorecptr->crrct_link_count = 0; inorecptr->crrct_prnt_inonum = 0; inorecptr->adj_entries = 0; inorecptr->cant_chkea = 0; inorecptr->clr_ea_fld = 0; inorecptr->clr_acl_fld = 0; inorecptr->inlineea_on = 0; inorecptr->inlineea_off = 0; inorecptr->inline_data_err = 0; inorecptr->ignore_alloc_blks = 0; inorecptr->reconnect = 0; inorecptr->unxpctd_prnts = 0; inorecptr->badblk_inode = 0; inorecptr->involved_in_dups = 0; inorecptr->inode_type = metadata_inode; inorecptr->link_count = 0; inorecptr->parent_inonum = 0; inorecptr->ext_rec = NULL; raitp1a_rc = record_valid_inode(ino_ptr, ino_idx, inorecptr, msg_info_ptr); } if (raitp1a_rc == FSCK_OK) { /* recorded it successfully */ inorecptr->in_use = 1; } } } if (raitp1a_rc == FSCK_OK) { /* self, bmap, and journal inodes recorded ok */ /* try for the bad block inode */ ino_idx = BADBLOCK_I; msg_info_ptr->msg_inonum = ino_idx; raitp1a_rc = inode_get(aggregate_inode, which_ait, ino_idx, &ino_ptr); if (raitp1a_rc == FSCK_OK) { /* got the bad block inode */ raitp1a_rc = get_inorecptr(aggregate_inode, alloc_ifnull, ino_idx, &inorecptr); if ((raitp1a_rc == FSCK_OK) && (inorecptr == NULL)) { raitp1a_rc = FSCK_INTERNAL_ERROR_59; fsck_send_msg(fsck_INTERNALERROR, raitp1a_rc, 0, 0, 0); } else if (raitp1a_rc == FSCK_OK) { inorecptr->in_use = 0; inorecptr->selected_to_rls = 0; inorecptr->crrct_link_count = 0; inorecptr->crrct_prnt_inonum = 0; inorecptr->adj_entries = 0; inorecptr->cant_chkea = 0; inorecptr->clr_ea_fld = 0; inorecptr->clr_acl_fld = 0; inorecptr->inlineea_on = 0; inorecptr->inlineea_off = 0; inorecptr->inline_data_err = 0; inorecptr->ignore_alloc_blks = 0; inorecptr->reconnect = 0; inorecptr->unxpctd_prnts = 0; inorecptr->badblk_inode = 0; inorecptr->involved_in_dups = 0; inorecptr->inode_type = metadata_inode; inorecptr->link_count = 0; inorecptr->parent_inonum = 0; inorecptr->ext_rec = NULL; raitp1a_rc = record_valid_inode(ino_ptr, ino_idx, inorecptr, msg_info_ptr); } if (raitp1a_rc == FSCK_OK) { /* recorded it successfully */ inorecptr->in_use = 1; } } } return (raitp1a_rc);}/************************************************************************** * NAME: record_fixed_metadata * * FUNCTION: Certain aggregate metadata is not described by any inode. * This routine marks, in the fsck workspace block map, that * the blocks occupied by this aggregate metadata are in use. * * PARAMETERS: none * * RETURNS: * success: FSCK_OK * failure: something else */int record_fixed_metadata(){ int rfm_rc = FSCK_OK; int64_t start_block, end_block; uint32_t length_in_agg_blocks; int64_t wsp_blocks_described; /* * the reserved space (at the beginning of the aggregate) */ start_block = 0; length_in_agg_blocks = AGGR_RSVD_BYTES / sb_ptr->s_bsize; end_block = start_block + length_in_agg_blocks - 1; rfm_rc = blkall_increment_owners(start_block, end_block, NULL); /* * the superblocks */ if (rfm_rc == FSCK_OK) { /* go ahead with superblocks */ length_in_agg_blocks = SIZE_OF_SUPER / sb_ptr->s_bsize; /* * primary */ start_block = SUPER1_OFF / sb_ptr->s_bsize; end_block = start_block + length_in_agg_blocks - 1; rfm_rc = blkall_increment_owners(start_block, end_block, NULL); /* * secondary */ if (rfm_rc == FSCK_OK) { start_block = SUPER2_OFF / sb_ptr->s_bsize; end_block = start_block + length_in_agg_blocks - 1; rfm_rc = blkall_increment_owners(start_block, end_block, NULL); } } /* * note that the fsck workspace and journal log (at the end of the * aggregate) are not described by the block map (neither the * Aggregate Block Allocation Map nor the fsck Workspace Block Map) */ /* * the "phantom blocks" described by the last dmap page */ if (rfm_rc == FSCK_OK) { /* * the first page is a control page and scratch area. */ wsp_blocks_described = BITSPERBYTE * (agg_recptr->ondev_wsp_byte_length - BYTESPERPAGE); if (wsp_blocks_described > agg_recptr->sb_agg_fsblk_length) { /* * the dmaps do describe more blocks than * actually exist */ /* since this is * the number of blocks and since blocks are * numbered starting at 0, this is the block * number of the first phantom block; */ start_block = agg_recptr->sb_agg_fsblk_length; end_block = wsp_blocks_described - 1; rfm_rc = blkall_increment_owners(start_block, end_block, NULL); } } return (rfm_rc);}/************************************************************************** * NAME: record_other_ait * * FUNCTION: Record the blocks occupied by the "other ait" in the fsck * workspace block map. To be more specific, if the primary * ait is being used for fsck processing, the secondary ait * is the "other ait"...and vice versa. * * PARAMETERS: none * * RETURNS: * success: FSCK_OK * failure: something else */int record_other_ait(){ int roa_rc = FSCK_OK; int64_t start_block, end_block; uint32_t length_in_agg_blocks; /* * first extent of the agg inode map */ if (agg_recptr->primary_ait_4part1) { /* primary already recorded */ start_block = addressPXD(&(sb_ptr->s_aim2)); length_in_agg_blocks = lengthPXD(&(sb_ptr->s_aim2)); } else { /* secondary already recorded */ start_block = AIMAP_OFF / sb_ptr->s_bsize; length_in_agg_blocks = (AITBL_OFF - AIMAP_OFF) / sb_ptr->s_bsize; } end_block = start_block + length_in_agg_blocks - 1; roa_rc = blkall_increment_owners(start_block, end_block, NULL); /* * first extent of the agg inode table */ if (agg_recptr->primary_ait_4part1) { /* primary already recorded */ start_block = addressPXD(&(sb_ptr->s_ait2)); length_in_agg_blocks = lengthPXD(&(sb_ptr->s_ait2)); } else { /* secondary already recorded */ start_block = AITBL_OFF / sb_ptr->s_bsize; length_in_agg_blocks = INODE_EXTENT_SIZE / sb_ptr->s_bsize; } end_block = start_block + length_in_agg_blocks - 1; roa_rc = blkall_increment_owners(start_block, end_block, NULL); return (roa_rc);}/***************************************************************************** * NAME: replicate_superblock * * FUNCTION: Refresh both the primary and secondary superblocks in the * aggregate from the correct (and possibly updated) superblock * in the fsck buffer. * * PARAMETERS: none * * RETURNS: * success: FSCK_OK * failure: something else */int replicate_superblock(){ int rs_rc = FSCK_OK; /* write from the buffer to the primary superblock */ rs_rc = ujfs_put_superblk(Dev_IOPort, sb_ptr, 1); /* have to assume something got written */ agg_recptr->ag_modified = 1; if (rs_rc != FSCK_OK) { /* not good here is really bad */ agg_recptr->cant_write_primary_sb = 1; agg_recptr->ag_dirty = 1; /* mark the superblock in the buffer * to show the aggregate is dirty * (in case it isn't already marked * that way) */ sb_ptr->s_state |= FM_DIRTY; fsck_send_msg(fsck_CNTWRTSUPP); } else { /* wrote to the primary superblock */ agg_recptr->cant_write_primary_sb = 0; } /* write from the buffer to the secondary superblock */ rs_rc = ujfs_put_superblk(Dev_IOPort, sb_ptr, 0); /* have to assume something got written */ agg_recptr->ag_modified = 1; if (rs_rc == FSCK_OK) { /* wrote to secondary ok */ agg_recptr->cant_write_secondary_sb = 0; } else { /* not good here is pretty bad */ agg_recptr->cant_write_secondary_sb = 1; fsck_send_msg(fsck_CNTWRTSUPS); if ((sb_ptr->s_state & FM_DIRTY) != FM_DIRTY) { /* superblk not marked dirty now */ /* * This means, among other things, that we just * did a successful write to the primary superblock * and that we marked the primary to say the aggregate * is clean. */ sb_ptr->s_state |= FM_DIRTY; /* write from the buffer to the primary superblock */ rs_rc = ujfs_put_superblk(Dev_IOPort, sb_ptr, 1); /* have to assume something got written */ agg_recptr->ag_modified = 1; if (rs_rc != FSCK_OK) { /* not good here is a disaster */ /* * We may have just taken an aggregate marked dirty and * changed it to clean, but now we discover that it really * does have a serious problem. And all we can do about * it is issue the strongest warning we can think up. */ agg_recptr->cant_write_primary_sb = 1; fsck_send_msg(fsck_CNTWRTSUPP); fsck_send_msg(fsck_AGGDRTYNOTCLN, Vol_Label); } } } if ((agg_recptr->cant_write_primary_sb) && (agg_recptr->cant_write_secondary_sb)) { /* both bad */ rs_rc = FSCK_FAILED_BTHSBLK_WRITE; } else if (agg_recptr->cant_write_primary_sb) { /* primary bad */ rs_rc = FSCK_FAILED_PSBLK_WRITE; } else if (agg_recptr->cant_write_secondary_sb) { /* secondary bad */ rs_rc = FSCK_FAILED_SSBLK_WRITE; } return (rs_rc);}/***************************************************************************** * NAME: rootdir_tree_bad * * FUNCTION: This routine is called if the B+ Tree rooted in the fileset * root directory (aggregate inode FILESET_I) is found to be * corrupt. If the user approves the repair, it makes the * root directory B+ tree a correct, empty tree. * * PARAMETERS: * inoptr - input - pointer to the inode in an fsck buffer * inode_updated - input - pointer to a variable in which to return * !0 if the inode (in the buffer) has been * modified by this routine * 0 if the inode (in the buffer) has not been * modified by this routine * * RETURNS: * success: FSCK_OK * failure: something else */int rootdir_tree_bad(struct dinode *inoptr, int *inode_updated){ int rtb_rc = FSCK_OK; *inode_updated = 0; fsck_send_msg(fsck_RIBADTREE); init_dir_tree((dtroot_t *) & (inoptr->di_btroot)); inoptr->di_next_index = 2; inoptr->di_nblocks = 0; inoptr->di_nlink = 2; inoptr->di_size = IDATASIZE; *inode_updated = 1; agg_recptr->rootdir_rebuilt = 1; fsck_send_msg(fsck_RICRETREE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -