📄 fsckino.c
字号:
/* ea format is bad */ ea_format_bad = -1; } } } else { /* else the EA is a single extent */ ext_length = lengthDXD(dxd_ptr); shortest_valid = (ext_length - 1) * sb_ptr->s_bsize + 1; longest_valid = ext_length * sb_ptr->s_bsize; if ((ext_length == 0) || (dxd_ptr->size < shortest_valid) || (dxd_ptr->size > longest_valid)) { /* invalid length */ fsck_send_msg(fsck_BADINODXDFLDL, fsck_ref_msg(msg_info_ptr->msg_inotyp), fsck_ref_msg(msg_info_ptr->msg_inopfx), msg_info_ptr->msg_inonum, fsck_ref_msg(msg_info_ptr->msg_dxdtyp)); extent_is_valid = 0; inorecptr->ignore_ea_blks = 1; } else { /* length and size might be ok */ agg_recptr->this_inode.ea_blks = ext_length; ext_address = addressDXD(dxd_ptr); vea_rc = process_extent(inorecptr, ext_length, ext_address, -1, 0, msg_info_ptr, &recorded_length, &extent_is_valid, FSCK_RECORD_DUPCHECK); /* * add the blocks in the EA extent to the running * totals for the filese and inode, but not for the * object represented by the object. */ agg_recptr->blocks_this_fset += recorded_length; agg_recptr->this_inode.all_blks += recorded_length; } if (!extent_is_valid) { inorecptr->clr_ea_fld = 1; agg_recptr->corrections_needed = 1; goto out; } /* the extent looks ok so need to check ea data structure */ ext_byte_length = ext_length * sb_ptr->s_bsize; if (ext_byte_length > agg_recptr->ea_buf_length) { /* extra large ea -- can't check it */ inorecptr->cant_chkea = 1; agg_recptr->warning_pending = 1; goto out; } /* regular size ea */ intermed_rc = ea_get(ext_address, ext_byte_length, agg_recptr->ea_buf_ptr, &(agg_recptr->ea_buf_length), &(agg_recptr->ea_buf_data_len), &(agg_recptr->ea_agg_offset)); if (intermed_rc != FSCK_OK) { fsck_send_msg(fsck_BADINODXDFLDO, fsck_ref_msg(msg_info_ptr->msg_inotyp), fsck_ref_msg(msg_info_ptr->msg_inopfx), msg_info_ptr->msg_inonum, fsck_ref_msg(msg_info_ptr->msg_dxdtyp)); inorecptr->clr_ea_fld = 1; agg_recptr->corrections_needed = 1; goto out; } /* the ea has been read into the regular buffer */ vea_rc = jfs_ValidateFEAList((struct FEALIST *) agg_recptr->ea_buf_ptr, dxd_ptr->size, &eafmt_error); if ((vea_rc != FSCK_OK) || (eafmt_error != 0)) { /* ea format is bad */ ea_format_bad = -1; } } out: if (ea_format_bad) { /* bad ea but haven't notified anyone */ fsck_send_msg(fsck_EAFORMATBAD, fsck_ref_msg(msg_info_ptr->msg_inotyp), fsck_ref_msg(msg_info_ptr->msg_inopfx), msg_info_ptr->msg_inonum); inorecptr->clr_ea_fld = 1; agg_recptr->corrections_needed = 1; vea_rc = FSCK_OK; } return (vea_rc);}/***************************************************************************** * NAME: validate_record_fileset_inode * * FUNCTION: Determine whether structures in and/or rooted in the specified * fileset owned inode are consistent and (as far as fsck can tell) * correct. Record, in the fsck workspace block map, all storage * allocated to the inode. * * PARAMETERS: * inonum - input - ordinal number of the inode in the * internal JFS format * inoidx - input - ordinal number of the inode as an integer * inoptr - input - pointer to the current inode * ino_msg_info_ptr - input - pointer to a record with information needed * to issue messages about the current inode * * RETURNS: * success: FSCK_OK * failure: something else */int validate_record_fileset_inode(uint32_t inonum, uint32_t inoidx, struct dinode *inoptr, struct fsck_ino_msg_info *ino_msg_info_ptr){ int vrfi_rc = FSCK_OK; int intermed_rc = FSCK_OK; struct fsck_inode_record *inorecptr; int8_t bad_size = 0; int aggregate_inode = 0; int alloc_ifnull = -1; int64_t min_size, max_size; int16_t size16; int8_t dinode_sect4_avail = 0; struct dinode an_inode; ino_msg_info_ptr->msg_inonum = inonum; vrfi_rc = get_inorecptr(aggregate_inode, alloc_ifnull, inoidx, &inorecptr); if (vrfi_rc != FSCK_OK) goto out; inorecptr->in_use = 1; if (!(inode_type_recognized(inoptr))) { /* bad type */ inorecptr->inode_type = unrecognized_inode; ino_msg_info_ptr->msg_inotyp = fsck_file; inorecptr->selected_to_rls = 1; inorecptr->ignore_alloc_blks = 1; /* no matter what the user * approves or disapproves, we aren't * going to even look to see which * blocks are allocated to this inode * (except for the blocks it occupies * itself) */ agg_recptr->corrections_needed = 1; fsck_send_msg(fsck_BADINOTYP, fsck_ref_msg(ino_msg_info_ptr->msg_inopfx), ino_msg_info_ptr->msg_inonum); goto out; } /* else type is recognized as valid */ /* * clear the workspace area for the current inode */ memset((void *) (&(agg_recptr->this_inode)), '\0', sizeof (agg_recptr->this_inode)); memcpy((void *) &(agg_recptr->this_inode.eyecatcher), (void *) "thisinod", 8); /* * finish filling in the inode's workspace record */ if (ISDIR(inoptr->di_mode)) { inorecptr->inode_type = directory_inode; ino_msg_info_ptr->msg_inotyp = fsck_directory; } else if (ISLNK(inoptr->di_mode)) { inorecptr->inode_type = symlink_inode; ino_msg_info_ptr->msg_inotyp = fsck_symbolic_link; } else if (ISBLK(inoptr->di_mode)) { inorecptr->inode_type = block_special_inode; ino_msg_info_ptr->msg_inotyp = fsck_block_special; } else if (ISCHR(inoptr->di_mode)) { inorecptr->inode_type = char_special_inode; ino_msg_info_ptr->msg_inotyp = fsck_char_special; } else if (ISFIFO(inoptr->di_mode)) { inorecptr->inode_type = FIFO_inode; ino_msg_info_ptr->msg_inotyp = fsck_FIFO; } else if (ISSOCK(inoptr->di_mode)) { inorecptr->inode_type = SOCK_inode; ino_msg_info_ptr->msg_inotyp = fsck_SOCK; } else { /* a regular file */ inorecptr->inode_type = file_inode; ino_msg_info_ptr->msg_inotyp = fsck_file; } inorecptr->link_count -= inoptr->di_nlink; /* * validate the inode's structures */ /* validate the Extended Attributes if any */ vrfi_rc = validate_EA(inoptr, inoidx, inorecptr, ino_msg_info_ptr); if (vrfi_rc != FSCK_OK) goto out; /* validate the Access Control List if any */ vrfi_rc = validate_ACL(inoptr, inoidx, inorecptr, ino_msg_info_ptr); if (vrfi_rc != FSCK_OK) goto out; /* nothing fatal with the EA or ACL */ if (inorecptr->inode_type == directory_inode) { /* * validate the data, if any, whether inline, * a single extent, or a B+ Tree */ vrfi_rc = validate_dir_data(inoptr, inoidx, inorecptr, ino_msg_info_ptr); } else if (ISREG(inoptr->di_mode) || ISLNK(inoptr->di_mode)) { /* * validate the data, if any, whether * inline, a single extent, or a B+ Tree */ vrfi_rc = validate_data(inoptr, inoidx, inorecptr, ino_msg_info_ptr); } if (vrfi_rc != FSCK_OK) goto out; if (inorecptr->ignore_alloc_blks) { inorecptr->selected_to_rls = 1; agg_recptr->corrections_needed = 1; } if (!inorecptr->selected_to_rls) { /* not selected to release yet */ if (inoptr->di_nblocks != agg_recptr->this_inode.all_blks) { /* * number of blocks is wrong. tree must be bad */#ifdef _JFS_DEBUG printf ("inode: %ld (t) di_nblocks = %lld (t) " "this_inode.all_blks = %lld (t)\n", inonum, inoptr->di_nblocks, agg_recptr->this_inode.all_blks);#endif fsck_send_msg(fsck_BADKEYS, fsck_ref_msg(ino_msg_info_ptr->msg_inotyp), fsck_ref_msg(ino_msg_info_ptr->msg_inopfx), ino_msg_info_ptr->msg_inonum, 9); inorecptr->selected_to_rls = 1; inorecptr->ignore_alloc_blks = 1; agg_recptr->corrections_needed = 1; bad_size = -1; } else { /* * the data size (in bytes) must not exceed the total * size of the blocks allocated for it and must use at * least 1 byte in the last fsblock allocated for it. */ if (agg_recptr->this_inode.data_size == 0) { if (inorecptr->inode_type == directory_inode) { min_size = IDATASIZE; max_size = IDATASIZE; } else { /* not a directory */ min_size = 0; max_size = IDATASIZE; } } else { /* blocks are allocated to data */ min_size = agg_recptr->this_inode.data_size - sb_ptr->s_bsize + 1; max_size = agg_recptr->this_inode.data_size; } /* Don't worry about directory size yet */ if (!ISDIR(inoptr->di_mode) && ((inoptr->di_size < min_size) || (!(inoptr->di_mode & ISPARSE) && (inoptr->di_size > max_size)))) { /* if size is less than min, or if object is * not sparse and size is greater than max, * then object size (in bytes) is is wrong * - tree must be bad. */#ifdef _JFS_DEBUG printf ("inode: %ld (t) min_size = %lld (t) " "max_size = %lld (t) di_size = %lld (t)\n", inonum, min_size, max_size, inoptr->di_size);#endif fsck_send_msg(fsck_BADKEYS, fsck_ref_msg(ino_msg_info_ptr->msg_inotyp), fsck_ref_msg(ino_msg_info_ptr->msg_inopfx), ino_msg_info_ptr->msg_inonum, 10); inorecptr->selected_to_rls = 1; inorecptr->ignore_alloc_blks = 1; agg_recptr->corrections_needed = 1; bad_size = -1; } } } if (!(inorecptr->ignore_alloc_blks)) { /* the tree looks ok */ intermed_rc = in_inode_data_check(inorecptr, ino_msg_info_ptr); if (inorecptr->selected_to_rls) { fsck_send_msg(fsck_BADKEYS, fsck_ref_msg(ino_msg_info_ptr->msg_inotyp), fsck_ref_msg(ino_msg_info_ptr->msg_inopfx), ino_msg_info_ptr->msg_inonum, 39); goto out; } /* not selected to release */ /* in_inode_data_check came out ok. * now check to be sure the mode bit INLINEEA is set properly * * N.B. if not, we'll correct the mode bit. We won't * release the inode for this. */ dinode_sect4_avail = 0; /* if in-inode data (or * description of data) overflows this then * section 4 of the disk inode is NOT available */ size16 = sizeof (an_inode.di_inlinedata); if (agg_recptr->this_inode.in_inode_data_length > size16) { /* extra long inline data */ if ((inoptr->di_mode & INLINEEA) == INLINEEA) { inorecptr->inlineea_off = 1; } } else { /* not extra long inline data */ if ((!(agg_recptr->this_inode.ea_inline) || (inorecptr->clr_ea_fld)) && (!(agg_recptr->this_inode.acl_inline) || (inorecptr->clr_acl_fld))) { /* * if (either ea isn't inline OR ea being * cleared) AND (either acl isn't inline OR acl * being cleared) */ dinode_sect4_avail = -1; } /* * if we know section 4 is (or will be) available but * the flag is off, then flag it to turn the flag on. */ if ((dinode_sect4_avail) && ((inoptr->di_mode & INLINEEA) != INLINEEA)) { inorecptr->inlineea_on = 1; agg_recptr->corrections_needed = 1; } else if ((!dinode_sect4_avail) && ((inoptr->di_mode & INLINEEA) == INLINEEA)) { /* * if we know section 4 is (or will be) * unavailable but the flag is on, then flag it * to turn the flag off. */ inorecptr->inlineea_off = 1; agg_recptr->corrections_needed = 1; } } } else { /* the tree is not valid */ /* * If bad_size is set then we didn't know that * the tree was bad until we looked at the size * fields. This means that the block usage recorded * for this inode has not been backed out yet. */ if (bad_size) { /* tree is bad by implication */ if (!inorecptr->ignore_ea_blks) { /* remove traces, in * the fsck workspace maps, of the blocks * allocated to this inode */ backout_EA(inoptr, inorecptr); } if (!inorecptr->ignore_acl_blks) { /* remove traces, in * the fsck workspace maps, of the blocks * allocated to this inode */ backout_ACL(inoptr, inorecptr); } if (inorecptr->inode_type == directory_inode) { /* * remove traces, in the fsck workspace * maps, of the blocks allocated to data * for this inode, whether a single * extent or a B+ Tree */ process_valid_dir_data(inoptr, inoidx, inorecptr, ino_msg_info_ptr, FSCK_UNRECORD); } else { /* * remove traces, in the fsck workspace * maps, of the blocks allocated to data * for this inode, whether a single * extent or a B+ Tree */ process_valid_data(inoptr, inoidx, inorecptr, ino_msg_info_ptr, FSCK_UNRECORD); } } } if ((vrfi_rc == FSCK_OK) && (!inorecptr->selected_to_rls)) { /* looks like a keeper */ agg_recptr->blocks_for_eas += agg_recptr->this_inode.ea_blks; agg_recptr->blocks_for_acls += agg_recptr->this_inode.acl_blks; if (inorecptr->inode_type == directory_inode) { /* a directory */ a
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -