📄 xchkdsk.c
字号:
* * PARAMETERS: none * * RETURNS: * success: FSCK_OK * failure: something else */int phase0_processing(){ int p0_rc = FSCK_OK; int64_t agg_blks; int32_t use_2ndary_superblock = 0; agg_recptr->logredo_rc = FSCK_OK; /* * if this flag is set then the primary superblock is * corrupt. The secondary superblock is good, but we * weren't able to fix the primary version. logredo can * run, but must use the secondary version of the * aggregate superblock */ if (agg_recptr->cant_write_primary_sb == 1) { use_2ndary_superblock = -1; } /* * start off phase 0 */ fsck_send_msg(fsck_FSSMMRY1, sb_ptr->s_bsize); /* aggregate size in fs blocks, by the user's point of view. */ agg_blks = agg_recptr->sb_agg_fsblk_length + agg_recptr->ondev_jlog_fsblk_length + agg_recptr->ondev_fscklog_fsblk_length + agg_recptr->ondev_wsp_fsblk_length; fsck_send_msg(fsck_FSSMMRY2, (long long) agg_blks); /* * logredo processing */ if ((agg_recptr->processing_readwrite) && (!agg_recptr->parm_options_nologredo)) { /* read/write access AND user didn't say not to need to invoke logredo */ fsck_send_msg(fsck_PHASE0);#ifdef _JFS_DEBUG printf("JFS fsck calling logredo \n");#endif /* * write the superblock to commit any changes we have made in it */ if (use_2ndary_superblock) { /* put 2ndary */ ujfs_put_superblk(Dev_IOPort, sb_ptr, 0); } else { /* put primary */ ujfs_put_superblk(Dev_IOPort, sb_ptr, 1); } agg_recptr->logredo_rc = jfs_logredo(Vol_Label, Dev_IOPort, use_2ndary_superblock);#ifdef _JFS_DEBUG printf("JFS fsck back from logredo, rc = %ld \n", agg_recptr->logredo_rc);#endif /* If superblock is clean and log in use, it's okay */ if ((agg_recptr->logredo_rc == LOG_IN_USE) && (sb_ptr->s_state == FM_CLEAN)) agg_recptr->logredo_rc = FSCK_OK; if (agg_recptr->logredo_rc != FSCK_OK) { /* logredo failed */ fsck_send_msg(fsck_LOGREDOFAIL, agg_recptr->logredo_rc); } else { fsck_send_msg(fsck_LOGREDORC, agg_recptr->logredo_rc); } /* * logredo may change the superblock, so read it in again */ if (use_2ndary_superblock) { /* get 2ndary */ ujfs_get_superblk(Dev_IOPort, sb_ptr, 0); } else { /* get primary */ ujfs_get_superblk(Dev_IOPort, sb_ptr, 1); } } if (agg_recptr->parm_options[UFS_CHKDSK_IFDIRTY] && (!agg_recptr->parm_options_nologredo) && ((sb_ptr->s_state & FM_DIRTY) != FM_DIRTY) && (agg_recptr->logredo_rc == FSCK_OK) && ((sb_ptr->s_flag & JFS_BAD_SAIT) != JFS_BAD_SAIT)) { /* * user specified 'only if dirty' * and didn't specify 'omit logredo()' * and logredo was successful * and the aggregate is clean */ agg_recptr->fsck_is_done = 1; exit_value = FSCK_OK; } else if (agg_recptr->parm_options_logredo_only) { /* * User only wants to run logredo, no matter what. * Make sure we leave a dirty superblock marked dirty */ if (sb_ptr->s_state & FM_DIRTY) agg_recptr->ag_dirty = 1; agg_recptr->fsck_is_done = 1; exit_value = FSCK_OK; } /* * if things look ok so far, make storage allocated by logredo() * available to fsck processing. */ if (p0_rc == FSCK_OK) { p0_rc = release_logredo_allocs(); } if (p0_rc != FSCK_OK) { agg_recptr->fsck_is_done = 1; exit_value = FSCK_OP_ERROR; } /* * If we're done, make sure s_logdev is up to date in the superblock. * Otherwise, s_logdev will be updated in final_processing. */ if (agg_recptr->fsck_is_done && (Log.location & OUTLINELOG) && Log.devnum) { sb_ptr->s_logdev = Log.devnum; /* * write the superblock to commit the above change */ if (use_2ndary_superblock) { /* put 2ndary */ ujfs_put_superblk(Dev_IOPort, sb_ptr, 0); } else { /* put primary */ ujfs_put_superblk(Dev_IOPort, sb_ptr, 1); } } return (p0_rc);}/***************************************************************************** * NAME: phase1_processing * * FUNCTION: Initialize the fsck workspace. Process the aggregate-owned * inodes. Process fileset special inodes. * * If any aggregate block is now multiply-allocated, then it * is allocated to more than 1 special inode. Exit. * * Process all remaining inodes. Count links from directories * to their child inodes. * * PARAMETERS: none * * RETURNS: * success: FSCK_OK * failure: something else */int phase1_processing(){ int p1_rc = FSCK_OK; fsck_send_msg(fsck_PHASE1); if ((p1_rc = establish_io_buffers()) != FSCK_OK) goto p1_exit; /* I/O buffers established */ /* establish workspace related to the aggregate */ if ((p1_rc = establish_agg_workspace()) != FSCK_OK) goto p1_exit; /* aggregate workspace established */ if ((p1_rc = record_fixed_metadata()) != FSCK_OK) goto p1_exit; /* fixed metadata recorded */ /* * note that this processing will use the vlarge * buffer and then return it for reuse */ if ((p1_rc = validate_select_agg_inode_table()) != FSCK_OK) goto p1_exit; /* we have an ait to work with */ /* establish workspace related to the fileset */ if ((p1_rc = establish_fs_workspace()) != FSCK_OK) goto p1_exit; if ((p1_rc = record_dupchk_inode_extents()) != FSCK_OK) goto p1_exit; /* fs workspace established */ /* claim the vlarge buffer for * validating EAs. We do this now because * it IS possible that the root directory (validated * in the call that follows) has an EA attached. */ establish_ea_iobuf(); if ((p1_rc = allocate_dir_index_buffers()) != FSCK_OK) goto p1_exit; /* verify the metadata * inodes for all filesets in the aggregate */ if ((p1_rc = validate_fs_metadata()) != FSCK_OK) goto p1_exit; /* check for blocks allocated * to 2 or more metadata objects */ if ((p1_rc = fatal_dup_check()) != FSCK_OK) goto p1_exit; /* validate the fileset inodes */ p1_rc = validate_fs_inodes(); /* return the vlarge buffer for reuse */ agg_recptr->ea_buf_ptr = NULL; agg_recptr->ea_buf_length = 0; agg_recptr->vlarge_current_use = NOT_CURRENTLY_USED; p1_exit: if (p1_rc != FSCK_OK) { agg_recptr->fsck_is_done = 1; exit_value = FSCK_OP_ERROR; } return (p1_rc);}/***************************************************************************** * NAME: phase2_processing * * FUNCTION: Scan the inodes. If any inode has more than 1 link from * any single directory then, in Release I of JFS, the * directory must be corrupt. * * Count the link from each directory inode to its parent inode. * Verify that the link count stored in each in-use inode matches * the link count observed by fsck. If not, get (once to cover * all incorrect link counts) permission to correct them. * * PARAMETERS: none * * RETURNS: * success: FSCK_OK * failure: something else */int phase2_processing(){ int p2_rc = FSCK_OK; fsck_send_msg(fsck_PHASE2); p2_rc = check_dir_integrity(); if (p2_rc == FSCK_OK) { p2_rc = check_link_counts(); } if (p2_rc != FSCK_OK) { agg_recptr->fsck_is_done = 1; exit_value = FSCK_OP_ERROR; } return (p2_rc);}/***************************************************************************** * NAME: phase3_processing * * FUNCTION: If any mulitply-allocated blocks have been detected, find * the first reference to each. For each in-use directory inode, * verify that it has exactly 1 parent and that the parent inode * number stored in the inode matches the parent observed by * fsck. * * PARAMETERS: none * * RETURNS: * success: FSCK_OK * failure: something else */int phase3_processing(){ int p3_rc = FSCK_OK; fsck_send_msg(fsck_PHASE3); if (agg_recptr->unresolved_1stref_count > 0) { /* * there are unresolved first references to * multiply-allocated blocks */ /* see if any first * references are by aggregate fixed metadata */ p3_rc = first_ref_check_fixed_metadata(); } if ((p3_rc == FSCK_OK) && (agg_recptr->unresolved_1stref_count > 0)) { /* * there are still unresolved first references * to multiply-allocated blocks */ /* see if any first references are by aggregate metadata inodes */ p3_rc = first_ref_check_agg_metadata(); } if ((p3_rc == FSCK_OK) && (agg_recptr->unresolved_1stref_count > 0)) { /* * there are still unresolved first references * to multiply-allocated blocks */ /* see if any first references are by fileset metadata inodes */ p3_rc = first_ref_check_fs_metadata(); } if ((p3_rc == FSCK_OK) && (agg_recptr->unresolved_1stref_count > 0)) { /* * there are still unresolved first references * to multiply-allocated blocks */ /* see if any first references are by * inode extents (described in the IAGs) */ p3_rc = first_ref_check_inode_extents(); } if (p3_rc == FSCK_OK) { /* nothing fatal yet */ p3_rc = check_parents_and_first_refs(); } if (p3_rc != FSCK_OK) { agg_recptr->fsck_is_done = 1; exit_value = FSCK_OP_ERROR; } return (p3_rc);}/***************************************************************************** * NAME: phase4_processing * * FUNCTION: For each inode record, in fsck's workspace inode map, which * has been flagged for some repair, get permission to perform * the repair and adjust the map for repairs implied by approved * repairs. (E.g., if an inode is approved for release, then * any directory entry for the inode is approved for removal, * by implication.) * * PARAMETERS: none * * RETURNS: * success: FSCK_OK * failure: something else */int phase4_processing(){ int p4_rc = FSCK_OK; /* * issue this message whether or not there are any corrections to ask * about so that when the next message comes out the user will know * that notifications are completed. */ fsck_send_msg(fsck_PHASE4); if (agg_recptr->corrections_needed || agg_recptr->warning_pending) { /* * Get permission to perform indicated repairs. */ p4_rc = report_problems_setup_repairs(); } if (p4_rc != FSCK_OK) { agg_recptr->fsck_is_done = 1; exit_value = FSCK_OP_ERROR; } return (p4_rc);}/***************************************************************************** * NAME: phase5_processing * * FUNCTION: Detect problems related to inode connectedness. Identify * each unconnected, in-use inode and flag it for reconnection. * Identify each directory inode with multiple parents and get * permission to repair it. * * PARAMETERS: none * * RETURNS: * success: FSCK_OK * failure: something else */int phase5_processing(){ int p5_rc = FSCK_OK; fsck_send_msg(fsck_PHASE5); if (agg_recptr->processing_readwrite) { /* have read/write access */ p5_rc = check_connectedness(); if (p5_rc != FSCK_OK) { agg_recptr->fsck_is_done = 1; exit_value = FSCK_OP_ERROR; } } return (p5_rc);}/***************************************************************************** * NAME: phase6_processing * * FUNCTION: Perform all approved inode corrections. * * PARAMETERS: none * * RETURNS: * success: FSCK_OK * failure: something else */int phase6_processing(){ int p6_rc = FSCK_OK; int intermed_rc; fsck_send_msg(fsck_PHASE6); if (!agg_recptr->processing_readwrite || !agg_recptr->corrections_approved) goto p6_exit; /* * we're about to write repairs. if something stops * after we start and before we finish, we'll leave the * filesystem in an inconsistent state. * Mark the superblock (and write it to the disk) to * show the filesystem is unmountable. If we complete * successfully and all errors are corrected, we'll * be marking it clean later on. */ sb_ptr->s_state |= FM_DIRTY; /* write to the primary superblock on the device. */ ujfs_put_superblk(Dev_IOPort, sb_ptr, 1); /* * log the fact the the superblock * has just been marked dirty */ fsck_send_msg(fsck_REPAIRSINPROGRESS); if (agg_recptr->inode_reconn_extens != NULL) { /* * there are ino
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -