📄 fsckmeta.c
字号:
agg_recptr->inode_stamp = secondary_inode_stamp; } else { /* multiple points of failure. */ /* * try to go on by using part1 from one table and part 2 from the other */ if (vsait_rc == FSCK_OK) { /* nothing fatal */ if (primary_part1_good && (!secondary_part2_good) && (!secondary_part2_bad)) { /* * primary part 1 is good and haven't checked * secondary part 2 yet */ agg_recptr->inode_stamp = primary_inode_stamp; intermed_rc = ait_special_read_ext1(fsck_primary); if (intermed_rc == FSCK_OK) { vsait_rc = record_ait_part1_again (fsck_primary); } else { vsait_rc = FSCK_FAILED_CANTREADAITEXT4; } if (vsait_rc == FSCK_OK) { /* primary part1 re-recorded ok */ intermed_rc = ait_special_read_ext1 (fsck_secondary); if (intermed_rc != FSCK_OK) { /* didn't get it */ secondary_part2_bad = 1; cant_read_secondary = -1; } else { /* got the 1st extent of secondary AIT into the buffer */ 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; } else { /* secondary table, part 2 is good */ secondary_part2_good = -1; } } } } else if (secondary_part1_good && (!primary_part2_good) && (!primary_part2_bad)) { /* * secondary part 1 is good and haven't * checked primary part 2 yet */ agg_recptr->inode_stamp = secondary_inode_stamp; intermed_rc = ait_special_read_ext1(fsck_primary); if (intermed_rc != FSCK_OK) { /* didn't get it */ primary_part2_bad = -1; cant_read_primary = -1; } else { /* got the 1st extent of primary AIT into the buffer */ 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; } else { /* primary table, part 2 is good */ primary_part2_good = 1; intermed_rc = ait_special_read_ext1 (fsck_secondary); if (intermed_rc == FSCK_OK) { vsait_rc = record_ait_part1_again (fsck_secondary); } else { vsait_rc = FSCK_FAILED_CANTREADAITEXT5; } } } } } if (vsait_rc == FSCK_OK) { if (primary_part1_good && secondary_part2_good) { agg_recptr->primary_ait_4part1 = 1; agg_recptr->primary_ait_4part2 = 0; } else if (secondary_part1_good && primary_part2_good) { agg_recptr->primary_ait_4part1 = 0; agg_recptr->primary_ait_4part2 = 1; } else { /* either both have bad part 1 or both have bad part 2 */ vsait_rc = FSCK_FAILED_BOTHAITBAD; } } } if (vsait_rc == FSCK_OK) { /* * get a record as placeholder for the reserved * aggregate inode */ vsait_rc = get_inorecptr(aggregate_inode, alloc_ifnull, 0, &inorecptr); if ((vsait_rc == FSCK_OK) && (inorecptr == NULL)) { vsait_rc = FSCK_INTERNAL_ERROR_36; fsck_send_msg(fsck_INTERNALERROR, vsait_rc, 0, 0, 0); } else if (vsait_rc == FSCK_OK) { /* got the record */ inorecptr->inode_type = metadata_inode; inorecptr->in_use = 1; } } else { if (cant_read_primary && cant_read_secondary) { /* this is fatal */ vsait_rc = FSCK_FAILED_CANTREADAITS; } } /* * Deal with the Aggregate Inode Map (and Table) not chosen * * If we're processing read-only and the primary versions are * ok, we need to verify that the secondary versions are * correctly redundant to the primary versions. */ if (vsait_rc == FSCK_OK) { /* a table is chosen */ if (agg_recptr->processing_readwrite) { /* * have write access so we'll be refreshing * the redundant version later on -- for now * just reserve the blocks for it. */ vsait_rc = record_other_ait(); } else { /* processing read-only */ if (primary_part1_good && primary_part2_good) { /* * need to verify that the secondary table and * map are correct redundant copies of the * primary table and map. */ vsait_rc = AIS_redundancy_check(); } else { /* either part1 or part2 of primary are invalid */ agg_recptr->ag_dirty = 1; } if (vsait_rc == FSCK_OK) { /* if it isn't correct a message has * been issued. Record the blocks they * way that we were unable to record the * occupy to avoid misleading error messages * later when we verify the block allocation * map. */ vsait_rc = record_other_ait(); } } } /* * report problems detected (if any) */ if (cant_read_primary) { fsck_send_msg(fsck_CANTREADAITP); } else if (primary_part1_bad || primary_part2_bad) { fsck_send_msg(fsck_ERRORSINAITP); } if (cant_read_secondary) { fsck_send_msg(fsck_CANTREADAITS); } else if (secondary_part1_bad || secondary_part2_bad) { fsck_send_msg(fsck_ERRORSINAITS); } if (cant_read_primary && cant_read_secondary) { agg_recptr->ag_dirty = 1; fsck_send_msg(fsck_CANTCONTINUE); } else if (primary_part1_bad && secondary_part1_bad) { agg_recptr->ag_dirty = 1; fsck_send_msg(fsck_CANTCONTINUE); } else if (primary_part2_bad && secondary_part2_bad) { agg_recptr->ag_dirty = 1; fsck_send_msg(fsck_CANTCONTINUE); } return (vsait_rc);}/***************************************************************************** * NAME: validate_super * * FUNCTION: This routine validates the JFS superblock currently in the * buffer. If any problem is detected, the which_superblock * input parm is used to tailor the message issued to notify * the user. * * PARAMETERS: * which_super - input - specifies the superblock which is in the * buffer { fsck_primary | fsck_secondary } * * RETURNS: * success: FSCK_OK * failure: something else */int validate_super(int which_super){ int vs_rc = 0; /* assume the superblock is ok */ int64_t bytes_on_device; int64_t agg_blks_in_aggreg = 0, agg_blks_on_device = 0, dev_blks_on_device; int64_t fsck_start_from_pxd, fsck_blkmap_start_blks; uint32_t fsck_length_from_pxd, fsck_blkmap_size_blks, fsck_blkmap_size_pages; int64_t jlog_start_from_pxd; uint32_t jlog_length_from_pxd; int32_t agl2size; uint32_t expected_flag = JFS_GROUPCOMMIT; uint32_t agsize; int bad_bsize = 0; if (memcmp(sb_ptr->s_magic, JFS_MAGIC, sizeof (sb_ptr->s_magic)) != 0) { vs_rc = FSCK_BADSBMGC; fsck_send_msg(fsck_BADSBMGC, fsck_ref_msg(which_super)); } else if (sb_ptr->s_version > JFS_VERSION) { vs_rc = FSCK_BADSBVRSN; fsck_send_msg(fsck_BADSBVRSN, fsck_ref_msg(which_super)); } else { /* the magic number and version number are correct so it * probably is a JFS superblock with the format we are expecting */ /* get physical device size */ ujfs_get_dev_size(Dev_IOPort, &bytes_on_device); dev_blks_on_device = bytes_on_device / Dev_blksize; if (sb_ptr->s_pbsize != Dev_blksize) { vs_rc = FSCK_BADSBOTHR1; fsck_send_msg(fsck_BADSBOTHR, "1", fsck_ref_msg(which_super)); } if (sb_ptr->s_l2pbsize != log2shift(Dev_blksize)) { vs_rc = FSCK_BADSBOTHR2; fsck_send_msg(fsck_BADSBOTHR, "2", fsck_ref_msg(which_super)); } if (!inrange(sb_ptr->s_bsize, 512, 4096)) { bad_bsize = -1; vs_rc = FSCK_BADSBOTHR3; fsck_send_msg(fsck_BADSBBLSIZ, fsck_ref_msg(which_super)); } else { /* else the filesystem block size is a legal value */ if (sb_ptr->s_l2bsize != log2shift(sb_ptr->s_bsize)) { vs_rc = FSCK_BADSBOTHR4; fsck_send_msg(fsck_BADSBOTHR, "4", fsck_ref_msg(which_super)); } if (sb_ptr->s_l2bfactor != log2shift(sb_ptr->s_bsize / Dev_blksize)) { vs_rc = FSCK_BADSBOTHR5; fsck_send_msg(fsck_BADSBOTHR, "5", fsck_ref_msg(which_super)); } if (sb_ptr->s_bsize < Dev_blksize) { bad_bsize = -1; vs_rc = FSCK_BLSIZLTLVBLSIZ; fsck_send_msg(fsck_BLSIZLTLVBLSIZ, fsck_ref_msg(which_super)); } } if (!bad_bsize) { /* the blocksize looks ok */ agg_blks_on_device = bytes_on_device / sb_ptr->s_bsize; if (sb_ptr->s_size > dev_blks_on_device) { vs_rc = FSCK_BADSBFSSIZ; fsck_send_msg(fsck_BADSBFSSIZ, fsck_ref_msg(which_super)); }#ifdef _JFS_DFS_LFS s_size_inbytes = sb_ptr->s_size * Dev_blksize; sum_inbytes = (int64_t) (sb_ptr->totalUsable * 1024) + (int64_t) (sb_ptr->minFree * 1024); if ((sum_inbytes > s_size_inbytes) || ((s_size_inbytes - sum_inbytes) >= 1024) ) { /* the sum is greater or the difference is at least 1K */ vs_rc = FSCK_BADBLKCTTTL; fsck_send_msg(fsck_BADBLKCTTTL, fsck_ref_msg(which_super)); }#endif /* _JFS_DFS_LFS */ if (((sb_ptr->s_flag & JFS_OS2) == JFS_OS2) || ((sb_ptr->s_flag & JFS_LINUX) == JFS_LINUX)) { /* must have JFS_OS2 or JFS_LINUX */ } else { vs_rc = FSCK_BADSBOTHR6; fsck_send_msg(fsck_BADSBOTHR, "6", fsck_ref_msg(which_super)); } if ((sb_ptr->s_flag & expected_flag) != expected_flag) { vs_rc = FSCK_BADSBOTHR6; fsck_send_msg(fsck_BADSBOTHR, "6", fsck_ref_msg(which_super)); } if (sb_ptr->s_agsize < (1 << L2BPERDMAP)) { vs_rc = FSCK_BADSBAGSIZ; fsck_send_msg(fsck_BADSBAGSIZ, fsck_ref_msg(which_super)); } else { /* else the alloc group size is possibly correct */ agg_blks_in_aggreg = sb_ptr->s_size * sb_ptr->s_pbsize / sb_ptr->s_bsize; agl2size = ujfs_getagl2size(agg_blks_in_aggreg, sb_ptr->s_bsize); agsize = (int64_t) 1 << agl2size; if (sb_ptr->s_agsize != agsize) { vs_rc = FSCK_BADAGFSSIZ; fsck_send_msg(fsck_BADSBAGSIZ, fsck_ref_msg(which_super)); } } } if (!vs_rc) { /* * check out the fsck in-aggregate workspace */ fsck_length_from_pxd = lengthPXD(&(sb_ptr->s_fsckpxd)); fsck_start_from_pxd = addressPXD(&(sb_ptr->s_fsckpxd)); agg_blks_in_aggreg = fsck_length_from_pxd + (sb_ptr->s_size * sb_ptr->s_pbsize / sb_ptr->s_bsize); if (agg_blks_in_aggreg > agg_blks_on_device) { /* wsp length is bad */ vs_rc = FSCK_BADSBFWSL1; fsck_send_msg(fsck_BADSBFWSL1, fsck_ref_msg(which_super)); } else { /* wsp length is plausible */ fsck_blkmap_size_pages = ((agg_blks_in_aggreg + (BITSPERPAGE - 1)) / BITSPERPAGE) + 1 + 50; /* size in aggregate blocks */ fsck_blkmap_size_blks = (fsck_blkmap_size_pages << L2PSIZE) / sb_ptr->s_bsize; /* * aggregate block offset of the fsck * workspace in the aggregate. */ fsck_blkmap_start_blks = agg_blks_in_aggreg - fsck_blkmap_size_blks; if (fsck_length_from_pxd != fsck_blkmap_size_blks) { /* * length of fsck in-aggregate workspace * is incorrect */ vs_rc = FSCK_BADSBFWSL; fsck_send_msg(fsck_BADSBFWSL, fsck_ref_msg(which_super)); } if (fsck_start_from_pxd != fsck_blkmap_start_blks) { /* * address of fsck in-aggregate workspace * is incorrect */ vs_rc = FSCK_BADSBFWSA; fsck_send_msg(fsck_BADSBFWSA, fsck_ref_msg(which_super)); } } } if (!vs_rc) { /* * check out the in-aggregate journal log * * if there is one it starts at the end of the fsck * in-aggregate workspace. */ jlog_length_from_pxd = lengthPXD(&(sb_ptr->s_logpxd)); jlog_start_from_pxd = addressPXD(&(sb_ptr->s_logpxd)); if (jlog_start_from_pxd != 0) { /* there's one in there */ if (jlog_start_from_pxd != agg_blks_in_aggreg) { /* * address of in-aggregate journal log * is incorrect */ vs_rc = FSCK_BADSBFJLA; fsck_send_msg(fsck_BADSBFJLA, fsck_ref_msg(which_super)); } agg_blks_in_aggreg += jlog_length_from_pxd; if (agg_blks_in_aggreg > agg_blks_on_device) { /* log length is bad */ vs_rc = FSCK_BADSBFJLL; fsck_send_msg(fsck_BADSBFJLL, fsck_ref_msg(which_super)); } } } if (!vs_rc) { /* * check out the descriptors for * the Secondary Agg Inode Table and the Secondary Agg Inode Map */ vs_rc = validate_super_2ndaryAI(which_super); } } /* end else the magic number and version number are correct so it * probably is a JFS superblock with the format we are expecting */ return (vs_rc);}/***************************************************************************** * NAME: validate_super_2ndaryAI * * FUNCTION: This routine validates, in the current superblock, the * descriptors for the Secondary Aggregate Inode Table and * the Secondary Aggregate Inode Map. * * If any problem is detected, the which_superblock input parm * is used to tailor the message issued to notify the user. * * PARAMETERS: * which_super - input - specifies the superblock which is in the * buffer { fsck_primary | fsck_secondary } * * RETURNS: * success: FSCK_OK *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -