📄 fsckmeta.c
字号:
return (rtb_rc);}/***************************************************************************** * NAME: validate_fs_metadata * * FUNCTION: Verify the metadata inodes for all filesets in the * aggregate. * * PARAMETERS: none * * RETURNS: * success: FSCK_OK * failure: something else */int validate_fs_metadata(){ int vfm_rc = FSCK_OK; int intermed_rc = FSCK_OK; struct fsck_ino_msg_info ino_msg_info; struct fsck_ino_msg_info *msg_info_ptr; int which_fsit, which_ait; uint32_t ino_idx; struct dinode *ino_ptr; int aggregate_inode = 0; /* going for fileset inodes only */ int alloc_ifnull = -1; int inode_updated; struct fsck_inode_record *inorecptr; msg_info_ptr = &ino_msg_info; /* all fileset owned */ msg_info_ptr->msg_inopfx = fsck_fset_inode; msg_info_ptr->msg_inotyp = fsck_metadata; if (agg_recptr->primary_ait_4part2) { which_ait = fsck_primary; } else { which_ait = fsck_secondary; } vfm_rc = ait_special_read_ext1(which_ait); if (vfm_rc != FSCK_OK) { /* read failed */ report_readait_error(vfm_rc, FSCK_FAILED_CANTREADAITEXTE, which_ait); vfm_rc = FSCK_FAILED_CANTREADAITEXTE; goto vfm_exit; } /* * In release 1 there's exactly 1 fileset */ which_fsit = FILESYSTEM_I; /* read the fileset superinode extension */ ino_idx = FILESET_EXT_I; intermed_rc = inode_get(aggregate_inode, which_fsit, ino_idx, &ino_ptr); if (intermed_rc != FSCK_OK) { /* can't get the inode */ //vfm_rc = FSCK_CANTREADFSEXT; //goto vfm_exit; goto read_root; /* Who really cares? */ } /* got superinode extension inode */ msg_info_ptr->msg_inonum = FILESET_EXT_I; intermed_rc = verify_fs_super_ext(ino_ptr, msg_info_ptr,&inode_updated); if (intermed_rc < 0) { /* something really really bad happened */ //vfm_rc = intermed_rc; //goto vfm_exit; goto read_root; } if (intermed_rc != FSCK_OK) { /* inode is bad */ //vfm_rc = FSCK_FSETEXTBAD; //goto vfm_exit; goto read_root; } /* superinode extension inode is ok */ if (inode_updated) { /* need to write the superinode extension */ vfm_rc = inode_put(ino_ptr); } //if (vfm_rc != FSCK_OK) // goto vfm_exit;read_root: /* read the root directory inode */ ino_idx = ROOT_I; intermed_rc = inode_get(aggregate_inode, which_fsit, ino_idx, &ino_ptr); if (intermed_rc < 0) { /* something really really bad happened */ vfm_rc = intermed_rc; goto vfm_exit; } if (intermed_rc != FSCK_OK) { /* can't get the inode */ vfm_rc = FSCK_CANTREADFSRTDR; goto vfm_exit; } /* got root directory inode */ msg_info_ptr->msg_inonum = ROOT_I; msg_info_ptr->msg_inotyp = fsck_directory; intermed_rc = verify_repair_fs_rootdir(ino_ptr, msg_info_ptr, &inode_updated); if (intermed_rc != FSCK_OK) { /* inode is bad. Couldn't (or * wasn't allowed to) repair it */ vfm_rc = FSCK_FSRTDRBAD; goto vfm_exit; } /* root directory is good */ if (inode_updated) { /* need to write the root directory */ vfm_rc = inode_put(ino_ptr); } /* * now get records as placeholders for * the 2 reserved fileset inodes */ vfm_rc = get_inorecptr(aggregate_inode, alloc_ifnull, FILESET_RSVD_I, &inorecptr); if ((vfm_rc == FSCK_OK) && (inorecptr == NULL)) { vfm_rc = FSCK_INTERNAL_ERROR_34; fsck_send_msg(fsck_INTERNALERROR, vfm_rc, 0, 0, 0); } else if (vfm_rc == FSCK_OK) { /* got first record */ inorecptr->inode_type = metadata_inode; inorecptr->in_use = 1; vfm_rc = get_inorecptr(aggregate_inode, alloc_ifnull, ACL_I, &inorecptr); if ((vfm_rc == FSCK_OK) && (inorecptr == NULL)) { vfm_rc = FSCK_INTERNAL_ERROR_35; fsck_send_msg(fsck_INTERNALERROR, vfm_rc, 0, 0, 0); } else if (vfm_rc == FSCK_OK) { /* got second record */ inorecptr->inode_type = metadata_inode; inorecptr->in_use = 1; } } vfm_exit: return (vfm_rc);}/***************************************************************************** * NAME: validate_repair_superblock * * FUNCTION: Verify that the primary superblock is valid. If it is, * the secondary superblock will be refreshed later in * processing. If the primary superblock is not valid, * verify that the secondary superblock is valid. If the * secondary superblock is found to be valid, copy it * over the primary superblock on the device so that * logredo will find a valid primary superblock. * * PARAMETERS: none * * RETURNS: * success: FSCK_OK * failure: something else */int validate_repair_superblock(){ int vrsb_rc = FSCK_OK; int intermed_rc = FSCK_OK; int primary_sb_bad = 1; /* assume a problem with primary */ int secondary_sb_bad = 1; /* assume a problem with secondary */ int which_sb = 0; /* get primary */ vrsb_rc = ujfs_get_superblk(Dev_IOPort, sb_ptr, 1); if (vrsb_rc != FSCK_OK) { /* if read primary fails */ fsck_send_msg(fsck_CNTRESUPP); } else { /* got primary superblock */ which_sb = fsck_primary; primary_sb_bad = validate_super(fsck_primary); } if (primary_sb_bad) { /* can't use the primary superblock */ /* get 2ndary */ vrsb_rc = ujfs_get_superblk(Dev_IOPort, sb_ptr, 0); if (vrsb_rc != FSCK_OK) { fsck_send_msg(fsck_CNTRESUPS); } else { /* got secondary superblock */ which_sb = fsck_secondary; secondary_sb_bad = validate_super(fsck_secondary); } if (!secondary_sb_bad) { /* secondary is ok */ if (agg_recptr->processing_readonly) { agg_recptr->ag_dirty = 1; agg_recptr->cant_write_primary_sb = 1; fsck_send_msg(fsck_BDSBNWRTACC); } else { /* else processing read/write */ sb_ptr->s_state = (sb_ptr->s_state | FM_DIRTY); /* correct the primary superblock */ intermed_rc = ujfs_put_superblk(Dev_IOPort, sb_ptr, 1); /* must assume something got written */ agg_recptr->ag_modified = 1; if (intermed_rc == FSCK_OK) { agg_recptr->ag_modified = 1; } else { /* write primary superblock failed */ /* * we won't bail out on this condition (so we * don't want to pass back the return code), * but it does leave the aggregate dirty */ agg_recptr->ag_dirty = 1; agg_recptr->cant_write_primary_sb = 1; fsck_send_msg(fsck_CNTWRTSUPP); } } } else { /* can't use the secondary superblock either */ agg_recptr->ag_dirty = 1; vrsb_rc = FSCK_FAILED_BTHSBLK_BAD; if ((primary_sb_bad == FSCK_BADSBMGC) && (secondary_sb_bad == FSCK_BADSBMGC)) { printf ("\nThe superblock does not describe a correct jfs file system.\n" "\nIf device %s is valid and contains a jfs file system,\n" "then both the primary and secondary superblocks are corrupt\n" "and cannot be repaired, and fsck cannot continue.\n" "\nOtherwise, make sure the entered device %s is correct.\n\n", Vol_Label, Vol_Label); } else { fsck_send_msg(fsck_BDSBBTHCRRPT); } if (Is_Device_Type_JFS(Vol_Label) == MSG_JFS_NOT_JFS) { fsck_send_msg(fsck_NOTJFSINFSTAB, Vol_Label); } } } if ((!primary_sb_bad) || (!secondary_sb_bad)) { /* the buffer holds a valid superblock */ /* aggregate block size */ agg_recptr->ag_blk_size = sb_ptr->s_bsize; if (which_sb == fsck_primary) { fsck_send_msg(fsck_SBOKP); } else { fsck_send_msg(fsck_SBOKS); } if ((sb_ptr->s_flag & JFS_SPARSE) == JFS_SPARSE) { fsck_send_msg(fsck_SPARSEFILSYS); } } return (vrsb_rc);}/***************************************************************************** * NAME: validate_select_agg_inode_table * * FUNCTION: Verify the inodes in the Aggregate Inode Table. If all * inodes in the Primary Aggregate Inode Table are valid, * select it. Otherwise, if all inodes in the Secondary * Aggregate Inode Table are valid, select it. Otherwise, * if inodes 0 through 15 are valid in one table and inodes * 16 through 31 are valid in the other, select the valid * 0 through 15 and the valid 16 through 31. * * PARAMETERS: none * * NOTES: o Aggregate inodes 0 through 15 describe the aggregate and * aggregate metadata. Aggregate inodes 16 through 31 each * describe a fileset in the aggregate (In release 1, there * is only 1 fileset in each aggregate and it is described * by aggregate inode 16). When neither Aggregate Inode * Table is completely valid, this suggests the division: * "part 1" is aggregate inodes 0 through 15 * "part 2" is aggregate inodes 16 through 31 * * o While we naturally prefer to use only the Primary Aggregate * Inode Table and, failing that, to use only the Secondary * Aggregate Inode Table, in the interests of avoiding loss * of user data, fsck will continue if it can find a valid * part 1 and a valid part 2. * * o Since this routine is invoked before the fsck workspace * has been completely initialized, this routine ensures * that the fsck I/O buffers contain the data needed by * any routine which it invokes. * * That is, since the workspace does not contain all the * information for inode_get (et al) to calculate device * offsets (needed to perform I/O), this routine ensures * that any invocations of inode_get by routines invoked * here will find the target data already in the fsck * inode buffer. * * RETURNS: * success: FSCK_OK * failure: something else */int validate_select_agg_inode_table(){ int vsait_rc = FSCK_OK; int intermed_rc = FSCK_OK; int aggregate_inode = -1; int alloc_ifnull = -1; struct fsck_inode_record *inorecptr; int cant_read_primary = 0; int cant_read_secondary = 0; int primary_part1_good = 0; int primary_part2_good = 0; int primary_part1_bad = 0; int primary_part2_bad = 0; int secondary_part1_good = 0; int secondary_part2_good = 0; int secondary_part1_bad = 0; int secondary_part2_bad = 0; uint32_t primary_inode_stamp = 0; uint32_t secondary_inode_stamp = 0; uint32_t unknown_stamp = (uint32_t) (-1); /* * try for part 1 and part 2 both from the primary aggregate inode table */ intermed_rc = ait_special_read_ext1(fsck_primary); if (intermed_rc != FSCK_OK) { /* don't have it in the buffer */ primary_part1_bad = -1; primary_part2_bad = -1; cant_read_primary = -1; } else { /* got the 1st extent of primary AIT into the inode buffer */ agg_recptr->inode_stamp = unknown_stamp; intermed_rc = verify_ait_part1(fsck_primary); primary_inode_stamp = agg_recptr->inode_stamp; if (intermed_rc < 0) { /* something fatal */ vsait_rc = intermed_rc; } else if (intermed_rc > 0) { /* primary table part 1 is bad */ primary_part1_bad = -1; } else { /* primary table, part 1 is good */ primary_part1_good = -1; intermed_rc = verify_ait_part2(fsck_primary); if (intermed_rc < 0) { /* something fatal */ vsait_rc = intermed_rc; } else if (intermed_rc > 0) { /* primary table part 2 is bad */ primary_part2_bad = -1; vsait_rc = backout_ait_part1(fsck_primary); } else { /* primary table, part 2 is good */ primary_part2_good = -1; } } } /* * if can't have both part 1 and part 2 from the primary, try for * part 1 and part 2 both from the secondary aggregate inode table */ if ((vsait_rc == FSCK_OK) && (primary_part1_bad || primary_part2_bad)) { /* go for secondary ait */ intermed_rc = ait_special_read_ext1(fsck_secondary); if (intermed_rc != FSCK_OK) { /* don't have it in the buffer */ secondary_part1_bad = -1; secondary_part2_bad = -1; cant_read_secondary = -1; } else { /* got the 1st extent of secondary AIT into the inode buffer */ agg_recptr->inode_stamp = unknown_stamp; intermed_rc = verify_ait_part1(fsck_secondary); secondary_inode_stamp = agg_recptr->inode_stamp; if (intermed_rc < 0) { /* something fatal */ vsait_rc = intermed_rc; } else if (intermed_rc > 0) { /* secondary table part 1 is bad */ secondary_part1_bad = 1; } else { /* secondary table, part 1 is good */ secondary_part1_good = 1; intermed_rc = verify_ait_part2(fsck_secondary); if (intermed_rc < 0) { /* something fatal */ vsait_rc = intermed_rc; } else if (intermed_rc > 0) { /* secondary table part 2 is bad */ secondary_part2_bad = 1; vsait_rc = backout_ait_part1(fsck_secondary); } else { /* secondary table, part 2 is good */ secondary_part2_good = 1; } } } } if ((vsait_rc == FSCK_OK) && (primary_part1_good && primary_part2_good)) { /* normal case, nothing amiss */ agg_recptr->primary_ait_4part1 = 1; agg_recptr->primary_ait_4part2 = 1; agg_recptr->inode_stamp = primary_inode_stamp; } else if ((vsait_rc == FSCK_OK) && (secondary_part1_good && secondary_part2_good)) { /* first safety net held up */ agg_recptr->primary_ait_4part1 = 0; agg_recptr->primary_ait_4part2 = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -