📄 xchkdsk.c
字号:
*/ intermed_rc = inode_get(is_aggregate, which_it, ROOT_I, &inoptr); if (intermed_rc == FSCK_OK) { intermed_rc = direntry_add(inoptr, agg_recptr->avail_inonum, agg_recptr->UniChar_lsfn_name); } if (intermed_rc == FSCK_OK) { /* added the entry */ /* increment the link count in the root * inode because we just added a subdirectory. * (Subdirectories point back to parent.) */ inoptr->di_nlink += 1; } else if (intermed_rc < 0) { /* it was fatal */ claf_rc = intermed_rc; } else { /* not successful, but not fatal */ claf_rc = FSCK_CANT_EXTEND_ROOTDIR; new_inorecptr->in_use = 0; } claf_setup_exit: if (claf_rc != FSCK_OK) { /* failed to create */ agg_recptr->lsfn_ok = 0; new_inorecptr->in_use = 0; fsck_send_msg(fsck_LSFNCNTCRE); } return (claf_rc);}/*************************************************************************** * NAME: final_processing * * FUNCTION: If processing read/write, replicate the superblock and the * aggregate inode structures (i.e., the Aggregate Inode Map * and the Aggregate Inode Table). * * Notify the user about various things. * * PARAMETERS: none * * RETURNS: * success: FSCK_OK * failure: something else */int final_processing(){ int pf_rc = FSCK_OK; int64_t observed_total_blocks, recorded_total_blocks; int64_t reportable_total_blocks; int64_t kbytes_for_dirs, kbytes_for_files; int64_t kbytes_for_eas, kbytes_for_acls; int64_t kbytes_total, kbytes_free, kbytes_reserved; int64_t block_surprise; /* * report extra or missing aggregate blocks * * Note that since the agg_record is instantiated in the * module (and not a malloc'ed space) it is still available * after the workspace has been released. * */ reportable_total_blocks = agg_recptr->blocks_used_in_aggregate + agg_recptr->free_blocks_in_aggregate; observed_total_blocks = reportable_total_blocks - agg_recptr->ondev_jlog_fsblk_length - agg_recptr->ondev_fscklog_fsblk_length - agg_recptr->ondev_wsp_fsblk_length; /* size in aggregate blocks */ recorded_total_blocks = sb_ptr->s_size * Dev_blksize / sb_ptr->s_bsize; if (observed_total_blocks > recorded_total_blocks) { block_surprise = observed_total_blocks - recorded_total_blocks; fsck_send_msg(fsck_XTRABLKS, (long long) block_surprise); } else if (recorded_total_blocks > observed_total_blocks) { block_surprise = recorded_total_blocks - observed_total_blocks; fsck_send_msg(fsck_MSSNGBLKS, (long long) block_surprise); } if (agg_recptr->processing_readwrite) { /* * Make sure the s_logdev is up to date in the superblock. */ if ((Log.location & OUTLINELOG) && Log.devnum) sb_ptr->s_logdev = Log.devnum; /* refresh the redundancy of the * aggregate superblock (and verify * successful write to the one we * haven't been using) */ pf_rc = replicate_superblock(); } /* * finish up processing */ fsck_send_msg(fsck_FSSMMRY3); /* * log the summary messages originally defined */ fsck_send_msg(fsck_FSSMMRY4, (long long) agg_recptr->blocks_for_inodes); fsck_send_msg(fsck_FSSMMRY5, (long long) agg_recptr->inodes_in_aggregate); fsck_send_msg(fsck_FSSMMRY6, (long long) agg_recptr->files_in_aggregate); fsck_send_msg(fsck_FSSMMRY9, (long long) agg_recptr->dirs_in_aggregate); fsck_send_msg(fsck_FSSMMRY7, (long long) reportable_total_blocks); fsck_send_msg(fsck_FSSMMRY8, (long long) agg_recptr->free_blocks_in_aggregate); /* * issue (and log) the standard messages */ /* number of blocks times bytes per block divided by bytes per kilobyte */ kbytes_total = reportable_total_blocks << agg_recptr->log2_blksize >> log2BYTESPERKBYTE; /* blocks for file inodes times bytes per block */ /* plus bytes for the file inodes themselves */ /* divided by bytes per kilobyte */ kbytes_for_dirs = ((agg_recptr->blocks_for_dirs << agg_recptr->log2_blksize) + (agg_recptr->dirs_in_aggregate << log2INODESIZE) ) >> log2BYTESPERKBYTE; /* blocks for file inodes times bytes per block */ /* plus bytes for the file inodes themselves */ /* divided by bytes per kilobyte */ kbytes_for_files = ((agg_recptr->blocks_for_files << agg_recptr->log2_blksize) + (agg_recptr->files_in_aggregate << log2INODESIZE) ) >> log2BYTESPERKBYTE; /* number of blocks times bytes per block divided by bytes per kilobyte */ kbytes_for_eas = agg_recptr->blocks_for_eas << agg_recptr->log2_blksize >> log2BYTESPERKBYTE; /* number of blocks times bytes per block divided by bytes per kilobyte */ kbytes_for_acls = agg_recptr->blocks_for_acls << agg_recptr->log2_blksize >> log2BYTESPERKBYTE; /* number of blocks times bytes per block divided by bytes per kilobyte */ kbytes_free = agg_recptr->free_blocks_in_aggregate << agg_recptr->log2_blksize >> log2BYTESPERKBYTE; /* everything else is reserved */ kbytes_reserved = kbytes_total - -kbytes_for_dirs - kbytes_for_files - kbytes_for_eas - kbytes_for_acls - kbytes_free; fsck_send_msg(fsck_STDSUMMARY1, (long long) kbytes_total); fsck_send_msg(fsck_STDSUMMARY2, (long long) kbytes_for_dirs, (long long) agg_recptr->dirs_in_aggregate); fsck_send_msg(fsck_STDSUMMARY3, (long long) kbytes_for_files, (long long) agg_recptr->files_in_aggregate); fsck_send_msg(fsck_STDSUMMARY4, (long long) kbytes_for_eas); fsck_send_msg(fsck_STDSUMMARY4A, (long long) kbytes_for_acls); fsck_send_msg(fsck_STDSUMMARY5, (long long) kbytes_reserved); fsck_send_msg(fsck_STDSUMMARY6, (long long) kbytes_free); if (pf_rc != FSCK_OK) { agg_recptr->fsck_is_done = 1; } return (pf_rc);}/***************************************************************************** * NAME: report_problems_setup_repairs * * FUNCTION: For each inode in the fileset, if fsck has determined that * any repairs are needed, get/verify permission to perform * the repair and, if permission has been given, adjust the * other inodes for implied repairs as appropriate. (E.g., * if inode a is released, then each directory inode parent * of a needs to have the entry for a removed.) * * PARAMETERS: none * * RETURNS: * success: FSCK_OK * failure: something else */int report_problems_setup_repairs(){ int rc = FSCK_OK; uint32_t ino_idx; int aggregate_inode = 0; /* going for fileset inodes only */ struct fsck_inode_ext_record *this_ext; struct fsck_inode_ext_record *ext_list; struct fsck_inode_record *this_inorec; int8_t other_adjustments; struct fsck_ino_msg_info ino_msg_info; struct fsck_ino_msg_info *msg_info_ptr; msg_info_ptr = &ino_msg_info; msg_info_ptr->msg_inopfx = fsck_fset_inode; /* all fileset owned */ rc = get_inorecptr_first(aggregate_inode, &ino_idx, &this_inorec); while ((rc == FSCK_OK) && (this_inorec != NULL)) { if (!((this_inorec->selected_to_rls) || (this_inorec->clr_ea_fld) || (this_inorec->clr_acl_fld) || (this_inorec->inlineea_on) || (this_inorec->inlineea_off) || (this_inorec->inline_data_err) || (this_inorec->cant_chkea) || (this_inorec->adj_entries) || (this_inorec->rebuild_dirtable) || ((this_inorec->unxpctd_prnts) && (!this_inorec->in_use)))) goto rpsr_next; /* * a record is allocated and flagged * for some repair (other than directory * with illegal hard links) or warning */ msg_info_ptr->msg_inonum = ino_idx; if (this_inorec->inode_type == directory_inode) { msg_info_ptr->msg_inotyp = fsck_directory; } else if (this_inorec->inode_type == symlink_inode) { msg_info_ptr->msg_inotyp = fsck_symbolic_link; } else if (this_inorec->inode_type == char_special_inode) { msg_info_ptr->msg_inotyp = fsck_char_special; } else if (this_inorec->inode_type == block_special_inode) { msg_info_ptr->msg_inotyp = fsck_block_special; } else if (this_inorec->inode_type == FIFO_inode) { msg_info_ptr->msg_inotyp = fsck_FIFO; } else if (this_inorec->inode_type == SOCK_inode) { msg_info_ptr->msg_inotyp = fsck_SOCK; } else { /* a regular file */ msg_info_ptr->msg_inotyp = fsck_file; } rc = display_paths(ino_idx, this_inorec, msg_info_ptr); if (rc != FSCK_OK) goto rpsr_next; if (!this_inorec->in_use) { /* not in use. */ if (this_inorec->unxpctd_prnts) { /* but with parents */ if (agg_recptr->processing_readwrite) { /* we can fix this */ rc = adjust_parents(this_inorec, ino_idx); agg_recptr->corrections_approved = 1; fsck_send_msg(fsck_WILLRMVBADREF); } else { /* don't have write access */ fsck_send_msg(fsck_INOBADREF); agg_recptr->ag_dirty = 1; } } else { /* shouldn't have created a record for it! */ rc = FSCK_INTERNAL_ERROR_2; } goto rpsr_next; } /* inode is in use */ if (this_inorec->selected_to_rls) { /* selected to release */ /* * explain the problem(s) */ if (this_inorec->inode_type == unrecognized_inode) { fsck_send_msg(fsck_BADINOFORMATO); } if (this_inorec->ignore_alloc_blks) { /* corrupt tree */ if (this_inorec->inode_type == file_inode) { fsck_send_msg(fsck_BADINODATAFORMAT); } else if (this_inorec->inode_type == directory_inode) { fsck_send_msg(fsck_BADINODATAFORMATD); } else { fsck_send_msg(fsck_BADINODATAFORMATO); } } if (this_inorec->inline_data_err) { /* invalid inline data spec */ if (this_inorec->inode_type == file_inode) { fsck_send_msg(fsck_BADINODATAFORMAT); } else if (this_inorec->inode_type == directory_inode) { fsck_send_msg(fsck_BADINODATAFORMATD); } else { fsck_send_msg(fsck_BADINODATAFORMATO); } } if (this_inorec->involved_in_dups) { if (this_inorec->inode_type == file_inode) { fsck_send_msg(fsck_BADINOCLAIMSDUPSF); } else if (this_inorec->inode_type == directory_inode) { fsck_send_msg(fsck_BADINOCLAIMSDUPSD); } else { fsck_send_msg(fsck_BADINOCLAIMSDUPSO); } } /* * notify of intentions (if any) */ if (agg_recptr->processing_readwrite) { /* we can fix this */ rc =adjust_parents(this_inorec, ino_idx); agg_recptr->corrections_approved = 1; fsck_send_msg(fsck_WILLRELEASEINO, fsck_ref_msg(msg_info_ptr->msg_inotyp), fsck_ref_msg(msg_info_ptr->msg_inopfx), msg_info_ptr->msg_inonum); } else { /* we don't have write access */ this_inorec->selected_to_rls = 0; /* * If the tree is corrupt, or the type is unrecognized, * keeping it makes the filesystem dirty. * Otherwise it's just the alleged owner of some * multiply allocated block(s). In the latter case, the * aggregate isn't necessarily dirty just because we don't * release this particular inode. If all other alleged * owners are released then this one becomes OK. After * all releases are done we'll check to see if any block(s) * are still multiply allocated, and if so we'll mark the * aggregate dirty. */ if ((this_inorec->inode_type == unrecognized_inode) || (this_inorec->ignore_alloc_blks)) { agg_recptr->ag_dirty =1; } fsck_send_msg(fsck_CANTREPAIRINO, fsck_ref_msg(msg_info_ptr->msg_inotyp), fsck_ref_msg(msg_info_ptr->msg_inopfx), msg_info_ptr->msg_inonum); } } if ( (rc != FSCK_OK) || this_inorec->ignore_alloc_blks || this_inorec->selected_to_rls ) goto rpsr_next; /* not corrupt and */ /* either never selected to release or * selected and release declined */ if ((rc == FSCK_OK) && (this_inorec->clr_ea_fld)) { /* clear EA */ if (agg_recptr->processing_readwrite) { /* we can fix this */ agg_recptr->corrections_approved = 1; fsck_send_msg(fsck_WILLCLEAREA); } else { /* we don't have write access */ this_inorec->clr_ea_fld = 0; agg_recptr->ag_dirty = 1; fsck_send_msg(fsck_INOEA); } } if ((rc == FSCK_OK) && (this_inorec->clr_acl_fld)) { /* clear ACL */ if (agg_recptr->processing_readwrite) { /* we can fix this */ agg_recptr->corrections_approved = 1; fsck_send_msg(fsck_WILLCLEARACL); } else { /* we don't have write access */ this_inorec->clr_acl_fld = 0; agg_recptr->ag_dirty = 1; fsck_send_msg(fsck_INOACL); } } if ((rc == FSCK_OK) && (this_inorec->inlineea_off)) { /* turn off sect 4 avail flag */ if (agg_recptr->processing_readwrite) { /* we can fix this */ agg_recptr->corrections_approved = 1; fsck_send_msg(fsck_WILLFIXINOMINOR); } else { /* we don't have write access */ this_inorec->inlineea_off = 0; agg_recptr->ag_dirty = 1; fsck_send_msg(fsck_INOMINOR); } } if ((rc == FSCK_OK) && (this_inorec->inlineea_on)) { /* turn on sect 4 avail flag */ if (agg_recptr->processing_readwrite) { /* we can fix this */ agg_recptr->corrections_approved = 1; fsck_send_msg(fsck_WILLFIXINOMINOR); } else { /* we don't have write access */ this_inorec->inlineea_on = 0; fsck_send_msg(fsck_INOMINOR); } } if ((rc == FSCK_OK) && (this_inorec->adj_entries)) { /* adjust dir entries */ other_adjustments = 0; ext_list = this_inorec->ext_rec; this_inorec->ext_rec = NULL; while (ext_list != NULL) { this_ext = ext_list; ext_list = ext_list->next; if ((this_ext->ext_type == add_direntry_extension) || (this_ext->ext_type == rmv_direntry_extension)) { other_adjustments = -1; agg_recptr->corrections_approved = 1; } if (this_ext->ext_type != rmv_badentry_extension) { this_ext->next = this_inorec->ext_rec; this_inorec->ext_rec = this_ext; } else { /* it represents a bad entry */ if (agg_recptr->processing_readwrite) { /* we can fix this */ agg_recptr-> corrections_approved = 1; this_ext->next = this_inorec->ext_rec; this_inorec->ext_rec = this_ext; other_adjustments = -1; fsck_send_msg (fsck_WILLRMVBADENTRY, fsck_ref_msg(msg_info_ptr->msg_inopfx), this_ext->inonum); } else { /* we don't have write access */ release_inode_extension (this_ext); agg_recptr->ag_dirty = 1; fsck_send_msg (fsck_BADDIRENTRY,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -