📄 fsckino.c
字号:
} return (iidc_rc);}/***************************************************************************** * NAME: inode_is_in_use * * FUNCTION: Determine whether the specified inode is currently being * used to represent a file system object. * * PARAMETERS: * inode_ptr - input - pointer to the current inode * inode_num - input - ordinal number of the inode in the internal * JFS format * * RETURNS: * 0: if inode is not in use * 1: if inode is in use */int inode_is_in_use(struct dinode *inode_ptr, uint32_t inode_num){ int iiiu_result; int ixpxd_unequal = 0; ixpxd_unequal = memcmp((void *) &(inode_ptr->di_ixpxd), (void *) &(agg_recptr->ino_ixpxd), sizeof (pxd_t)); iiiu_result = ((inode_ptr->di_inostamp == agg_recptr->inode_stamp) && (inode_ptr->di_number == inode_num) && (inode_ptr->di_fileset == agg_recptr->ino_fsnum) && (!ixpxd_unequal) && (inode_ptr->di_nlink != 0)); return (iiiu_result);}/***************************************************************************** * NAME: parent_count * * FUNCTION: Count the number of directory entries fsck has observed which * refer to the specified inode. * * PARAMETERS: * this_inorec - input - pointer to an fsck inode record describing the * current inode * * RETURNS: * the number of parent directories observed for the inode */int parent_count(struct fsck_inode_record *this_inorec){ int pc_result = 0; struct fsck_inode_ext_record *this_ext; if (this_inorec->parent_inonum != 0) { pc_result++; } this_ext = this_inorec->ext_rec; while (this_ext != NULL) { /* extension records to check */ if (this_ext->ext_type == parent_extension) { pc_result++; } this_ext = this_ext->next; } return (pc_result);}/***************************************************************************** * NAME: record_valid_inode * * FUNCTION: Record, in the fsck workspace block map, all aggregate blocks * allocated to the specified inode. The inode structures have * already been validated, no error checking is done. * * PARAMETERS: * inoptr - input - pointer to the current inode * inoidx - input - ordinal number of the inode as an integer * inorecptr - input - pointer to an fsck inode record describing the * current inode * 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 record_valid_inode(struct dinode *inoptr, uint32_t inoidx, struct fsck_inode_record *inorecptr, struct fsck_ino_msg_info *msg_info_ptr){ int rvi_rc = FSCK_OK; int64_t first_fsblk, last_fsblk; uint32_t num_fsblks; dxd_t *dxd_ptr; /* * record the extent (if any) containing the EA */ if (inoptr->di_ea.flag == DXD_EXTENT) { /* there is an ea to record */ dxd_ptr = &(inoptr->di_ea); first_fsblk = addressDXD(dxd_ptr); num_fsblks = lengthDXD(dxd_ptr); last_fsblk = first_fsblk + num_fsblks - 1; extent_record(first_fsblk, last_fsblk); agg_recptr->this_inode.all_blks += num_fsblks; agg_recptr->blocks_this_fset += num_fsblks; } /* * record the extent (if any) containing the ACL */ if (inoptr->di_acl.flag == DXD_EXTENT) { /* there is an acl to record */ dxd_ptr = &(inoptr->di_acl); first_fsblk = addressDXD(dxd_ptr); num_fsblks = lengthDXD(dxd_ptr); last_fsblk = first_fsblk + num_fsblks - 1; extent_record(first_fsblk, last_fsblk); agg_recptr->this_inode.all_blks += num_fsblks; agg_recptr->blocks_this_fset += num_fsblks; } /* * record the extents (if any) described as data */ process_valid_data(inoptr, inoidx, inorecptr, msg_info_ptr, FSCK_RECORD); return (rvi_rc);}/***************************************************************************** * NAME: release_inode * * FUNCTION: Release all aggregate blocks allocated to the specified inode. * Reset the link count, in the inode on the device, to zero * to make it available for reuse. * * PARAMETERS: * inoidx - input - ordinal number of the inode as an integer * ino_recptr - input - pointer to an fsck inode record describing the * current inode * inoptr - input - pointer to the current inode * * RETURNS: * success: FSCK_OK * failure: something else */int release_inode(uint32_t inoidx, struct fsck_inode_record *ino_recptr, struct dinode *inoptr){ int ri_rc = FSCK_OK; struct dinode *this_inode; int aggregate_inode = 0; /* going for fileset inodes only */ int which_it = 0; /* in release 1 there is only fileset 0 */ 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; msg_info_ptr->msg_inonum = inoidx; if (ino_recptr->inode_type == directory_inode) { msg_info_ptr->msg_inotyp = fsck_directory; } else if (ino_recptr->inode_type == symlink_inode) { msg_info_ptr->msg_inotyp = fsck_symbolic_link; } else if (ino_recptr->inode_type == char_special_inode) { msg_info_ptr->msg_inotyp = fsck_char_special; } else if (ino_recptr->inode_type == block_special_inode) { msg_info_ptr->msg_inotyp = fsck_block_special; } else if (ino_recptr->inode_type == FIFO_inode) { msg_info_ptr->msg_inotyp = fsck_FIFO; } else if (ino_recptr->inode_type == SOCK_inode) { msg_info_ptr->msg_inotyp = fsck_SOCK; } else { /* a regular file */ msg_info_ptr->msg_inotyp = fsck_file; } if (ino_recptr->in_use) { /* the inode is 'in use' */ ri_rc = inode_get(aggregate_inode, which_it, inoidx, &this_inode); if (ri_rc == FSCK_OK) { /* inode read successfully */ this_inode->di_nlink = 0; ri_rc = inode_put(this_inode); if ((ri_rc == FSCK_OK) && (!ino_recptr->ignore_alloc_blks)) { ri_rc = unrecord_valid_inode(this_inode, inoidx, ino_recptr, msg_info_ptr); } } } return (ri_rc);}/***************************************************************************** * NAME: unrecord_valid_inode * * FUNCTION: Unrecord, in the fsck workspace block map, all aggregate blocks * allocated to the specified inode. The inode structures have * already been validated, no error checking is done. * * PARAMETERS: * inoptr - input - pointer to the current inode * inoidx - input - ordinal number of the inode as an integer * inorecptr - input - pointer to an fsck inode record describing * the current inode * 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 unrecord_valid_inode(struct dinode *inoptr, uint32_t inoidx, struct fsck_inode_record *inorecptr, struct fsck_ino_msg_info *msg_info_ptr){ int uvi_rc = FSCK_OK; int64_t ea_blocks = 0; int64_t acl_blocks = 0; /* * unrecord the extent (if any) containing the EA */ if ((inoptr->di_ea.flag == DXD_EXTENT) && (!inorecptr->ignore_ea_blks)) { ea_blocks = lengthDXD(&(inoptr->di_ea)); agg_recptr->blocks_for_eas -= ea_blocks; uvi_rc = backout_EA(inoptr, inorecptr); } /* * unrecord the extent (if any) containing the ACL */ if ((inoptr->di_acl.flag == DXD_EXTENT) && (!inorecptr->ignore_acl_blks)) { acl_blocks = lengthDXD(&(inoptr->di_acl)); agg_recptr->blocks_for_acls -= acl_blocks; uvi_rc = backout_ACL(inoptr, inorecptr); } /* * unrecord the extents (if any) describing data * * note that the tree is valid or we'd be ignoring these allocated * blocks. */ if (uvi_rc == FSCK_OK) { if (inorecptr->inode_type == directory_inode) { agg_recptr->blocks_for_dirs -= inoptr->di_nblocks - ea_blocks; uvi_rc = process_valid_dir_data(inoptr, inoidx, inorecptr, msg_info_ptr, FSCK_UNRECORD); } else { agg_recptr->blocks_for_files -= inoptr->di_nblocks - ea_blocks; uvi_rc = process_valid_data(inoptr, inoidx, inorecptr, msg_info_ptr, FSCK_UNRECORD); } } return (uvi_rc);}/***************************************************************************** * NAME: validate_ACL * * FUNCTION: Determine whether the structures in the specified inode to * describe ACL data owned by the inode are consistent and (as * far as fsck can tell) correct. * * PARAMETERS: * inoptr - input - pointer to the current inode * inoidx - input - ordinal number of the inode as an integer * inorecptr - input - pointer to an fsck inode record describing * the current inode * 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_ACL(struct dinode *inoptr, uint32_t inoidx, struct fsck_inode_record *inorecptr, struct fsck_ino_msg_info *msg_info_ptr){ int vacl_rc = FSCK_OK; dxd_t *dxd_ptr; uint32_t recorded_length, shortest_valid, longest_valid; uint32_t ext_length; int64_t ext_address; int8_t extent_is_valid = 0; uint16_t size16; struct dinode an_inode; dxd_ptr = &(inoptr->di_acl); msg_info_ptr->msg_dxdtyp = fsck_ACL; if (dxd_ptr->flag == 0) goto out; /* there is an ACL for this inode */ if ((dxd_ptr->flag != DXD_EXTENT) && (dxd_ptr->flag != DXD_INLINE) && (dxd_ptr->flag != DXD_CORRUPT)) { /* not a single extent AND not inline AND not already * reported */ fsck_send_msg(fsck_BADINODXDFLDD, 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_acl_fld = 1; inorecptr->ignore_acl_blks = 1; agg_recptr->corrections_needed = 1; goto out; } /* else the acl flag is ok */ if (dxd_ptr->flag == DXD_INLINE) { /* ACL is inline */ size16 = sizeof (an_inode.di_inlineea); agg_recptr->this_inode.acl_inline = 1; agg_recptr->this_inode.inline_acl_length = (uint16_t) dxd_ptr->size; agg_recptr->this_inode.inline_acl_offset = (uint16_t) addressDXD(dxd_ptr); if ((dxd_ptr->size == 0) || (dxd_ptr->size > (size16 - agg_recptr->this_inode.inline_acl_offset))) { /* * the length extends * beyond the end of the inode */ 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)); inorecptr->clr_acl_fld = 1; agg_recptr->corrections_needed = 1; } } else if (dxd_ptr->flag == DXD_EXTENT) { /* else the ACL 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)); inorecptr->clr_acl_fld = 1; inorecptr->ignore_acl_blks = 1; agg_recptr->corrections_needed = 1; recorded_length = 0; extent_is_valid = 0; } else { /* length and size might be ok */ agg_recptr->this_inode.acl_blks = ext_length; ext_address = addressDXD(dxd_ptr); vacl_rc = process_extent(inorecptr, ext_length, ext_address, 0, -1, msg_info_ptr, &recorded_length, &extent_is_valid, FSCK_RECORD_DUPCHECK); /* * add the blocks in the ACL extent to the running * totals for the fileset 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_acl_fld = 1; agg_recptr->corrections_needed = 1; } } out: return (vacl_rc);}/***************************************************************************** * NAME: validate_data * * FUNCTION: Determine whether the structures in, or rooted in, the specified * non-directory inode to describe data owned by the inode are * consistent and (as far as fsck can tell) correct. * * PARAMETERS: * inoptr - input - pointer to the current inode * inoidx - input - ordinal number of the inode as an integer * inorecptr - input - pointer to an fsck inode record describing * the current inode * 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_data(struct dinode *inoptr, uint32_t inoidx, struct fsck_inode_record *inorecptr, struct fsck_ino_msg_info *msg_info_ptr){ int vd_rc = FSCK_OK; int intermed_rc = FSCK_OK; dxd_t *dxd_ptr; xtpage_t *xtp_ptr; dxd_ptr = &(inoptr->di_dxd); /* the data root dxd */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -