📄 fsckino.c
字号:
} else if ((parent_inorecptr->in_use) && (!parent_inorecptr->selected_to_rls) && (!parent_inorecptr->ignore_alloc_blks)) { /* got parent record and parent ok so far */ intermed_rc = get_path(inoidx, this_parent, this_path_ptr_ptr, ino_recptr); if (intermed_rc != FSCK_OK) { /* unable to obtain 1st path */ fsck_send_msg(fsck_INOCNTGETPATH, fsck_ref_msg(msg_info_ptr->msg_inopfx), this_parent, fsck_ref_msg(msg_info_ptr->msg_inotyp), fsck_ref_msg(msg_info_ptr->msg_inopfx), inoidx); if (intermed_rc < 0) { /* it's fatal */ dips_rc = intermed_rc; } } else { /* 1st path obtained */ a_path_displayed = -1; dips_rc = display_path(inoidx, msg_info_ptr-> msg_inopfx, this_parent, this_path_ptr, ino_recptr); /* * if there are any more paths to the * inode, find the next parent */ this_ext = ino_recptr->ext_rec; while ((this_ext != NULL) && (this_ext->ext_type != parent_extension)) { this_ext = this_ext->next; } } } } } while ((dips_rc == FSCK_OK) && (this_ext != NULL)) { /* there may be more parents */ if (this_ext->ext_type == parent_extension) { /* parent extension */ this_parent = this_ext->inonum; if ((this_parent != ROOT_I) || (!agg_recptr->rootdir_rebuilt)) { /* * either this parent isn't the root or else * the root dir has not been rebuilt */ intermed_rc = get_inorecptr(0, 0, this_parent, &parent_inorecptr); if (intermed_rc != 0) { /* it's fatal */ dips_rc = intermed_rc; } else if ((parent_inorecptr->in_use) && (!parent_inorecptr-> selected_to_rls) && (!parent_inorecptr-> ignore_alloc_blks)) { /* got parent record and parent seems * ok so far */ intermed_rc = get_path(inoidx, this_parent, this_path_ptr_ptr, ino_recptr); if (intermed_rc == FSCK_OK) { /* next path obtained */ a_path_displayed = -1; dips_rc = display_path(inoidx, msg_info_ptr-> msg_inopfx, this_parent, this_path_ptr, ino_recptr); } else { /* unable to obtain next path */ fsck_send_msg (fsck_INOCNTGETPATH, fsck_ref_msg(msg_info_ptr->msg_inopfx), this_parent, fsck_ref_msg(msg_info_ptr->msg_inotyp), fsck_ref_msg(msg_info_ptr->msg_inopfx), inoidx); if (intermed_rc < 0) { dips_rc = intermed_rc; } } } } } this_ext = this_ext->next; } /* * if nothing unexpected happened but we * couldn't display a path, issue a message * and go on. */ out: if ((dips_rc == FSCK_OK) && (!a_path_displayed)) { fsck_send_msg(fsck_INOCANTNAME, fsck_ref_msg(msg_info_ptr->msg_inotyp), fsck_ref_msg(msg_info_ptr->msg_inopfx), inoidx); } return (dips_rc);}/***************************************************************************** * NAME: first_ref_check_inode * * FUNCTION: Determine whether storage allocated to the given inode * includes any multiply-allocated blocks for which the * first reference is still unresolved. * * PARAMETERS: * inoptr - input - pointer to the current inode * inoidx - input - ordinal number of the inode as an integer * inorec_ptr - input - pointer to an fsck inode record describing the * current inode * msginfo_ptr - input - pointer to a record with information needed * to issue messages about the current inode * * RETURNS: * success: FSCK_OK * failure: something else */int first_ref_check_inode(struct dinode *inoptr, uint32_t inoidx, struct fsck_inode_record *inorec_ptr, struct fsck_ino_msg_info *msginfo_ptr){ int frcvi_rc = FSCK_OK; uint32_t block_count; int64_t first_fsblk; uint32_t num_fsblks; int8_t extent_is_valid; dxd_t *dxd_ptr; int is_EA; int is_ACL; /* * check 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); is_EA = -1; is_ACL = 0; msginfo_ptr->msg_dxdtyp = fsck_EA; frcvi_rc = process_extent(inorec_ptr, num_fsblks, first_fsblk, is_EA, is_ACL, msginfo_ptr, &block_count, &extent_is_valid, FSCK_QUERY); } /* * check 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); is_EA = 0; is_ACL = -1; msginfo_ptr->msg_dxdtyp = fsck_ACL; frcvi_rc = process_extent(inorec_ptr, num_fsblks, first_fsblk, is_EA, is_ACL, msginfo_ptr, &block_count, &extent_is_valid, FSCK_QUERY); } /* * check the extents (if any) described as data */ if (frcvi_rc == FSCK_OK) { if (inorec_ptr->inode_type == directory_inode) { frcvi_rc = process_valid_dir_data(inoptr, inoidx, inorec_ptr, msginfo_ptr, FSCK_QUERY); } else if (ISREG(inoptr->di_mode) || ISLNK(inoptr->di_mode)) { frcvi_rc = process_valid_data(inoptr, inoidx, inorec_ptr, msginfo_ptr, FSCK_QUERY); } } return (frcvi_rc);}/***************************************************************************** * NAME: get_path * * FUNCTION: Construct the unicode path from the root directory through * the entry in the specified parent directory. * * PARAMETERS: * inode_idx - input - ordinal number of the inode as an integer * parent_inonum - input - the inode number for the (parent) directory * whose entry to the current inode is to be * described by the contents of inopath. * addr_path_addr - input - pointer to a variable in which to return * the address of the path (in UniChars) * ino_recptr - input - pointer to an fsck inode record describing * the current inode * * RETURNS: * success: FSCK_OK * failure: something else */int get_path(uint32_t inode_idx, uint32_t parent_inonum, char **addr_path_addr, struct fsck_inode_record *ino_recptr){ int gip_rc = FSCK_OK; uint32_t inode_inonum; uint32_t this_parent_inonum; int bytes_used; int this_name_length = 0; int length_in_UniChars; UniChar uniname[256]; char *path_ptr; int path_idx; int path_completed = 0; uint32_t parent_idx; struct fsck_inode_record *parent_inorecptr; int aggregate_inode = 0; int alloc_ifnull = 0; *addr_path_addr = NULL; bytes_used = sizeof (char); path_idx = JFS_PATH_MAX - 1; agg_recptr->path_buffer[path_idx] = '\0'; path_ptr = &(agg_recptr->path_buffer[path_idx]); /* change the inode index to an inode number */ inode_inonum = (uint32_t) inode_idx; /* the first parent must be given since the object may not be a * directory */ this_parent_inonum = parent_inonum; if (inode_idx == 2) { /* it's the root directory */ path_completed = -1; path_idx--; path_ptr--; agg_recptr->path_buffer[path_idx] = agg_recptr->delim_char; } while ((!path_completed) && (gip_rc == FSCK_OK)) { gip_rc = direntry_get_objnam(this_parent_inonum, inode_inonum, &length_in_UniChars, uniname); uniname[length_in_UniChars] = 0; if (gip_rc != FSCK_OK) { /* didn't get the name */ path_completed = -1; if (path_idx != (JFS_PATH_MAX - 1)) { /* we got part of the path */ /* remove the foreslash from the * beginning of the path we have at this * beginning as now assembled it implies * that the unconnected dir parent is * connected to the fileset root directory. */ path_ptr++; } break; } this_name_length = Unicode_String_to_UTF8_String((uint8_t *) Str_Name, uniname, 256); Str_Name[this_name_length] = '\0'; if ((bytes_used + this_name_length + sizeof (char)) > JFS_PATH_MAX) { /* the path is beyond the legal length */ path_completed = -1; if (path_idx == (JFS_PATH_MAX - 1)) { /* the very first segment * is too long to be valid */ gip_rc = FSCK_FAILED_DIRENTRYBAD; } else { /* we got part of the path */ /* remove the foreslash from the * beginning of the path we have at * this point since as now assembled * it implies that the unconnected dir * parent is connected to the fileset * root directory. */ path_ptr++; } break; } bytes_used += this_name_length; path_idx -= this_name_length; path_ptr -= this_name_length; Str_Name_len = this_name_length; memcpy((void *) path_ptr, (void *) &Str_Name, Str_Name_len); bytes_used += sizeof (char); path_idx--; path_ptr--; agg_recptr->path_buffer[path_idx] = agg_recptr->delim_char; /* * assume that we'll find a parent dir for the * path segment just copied into the path buffer. */ if (this_parent_inonum == ROOT_I) { path_completed = -1; break; } /* haven't gotten up to root yet */ parent_idx = (uint32_t) this_parent_inonum; inode_inonum = this_parent_inonum; gip_rc = get_inorecptr(aggregate_inode, alloc_ifnull, parent_idx, &parent_inorecptr); if ((gip_rc == FSCK_OK) && (parent_inorecptr == NULL)) gip_rc = FSCK_INTERNAL_ERROR_21; if (gip_rc != FSCK_OK) break; this_parent_inonum = parent_inorecptr->parent_inonum; if ((this_parent_inonum == 0) || (parent_inorecptr->selected_to_rls) || (!(parent_inorecptr->in_use)) || (parent_inorecptr->inode_type == metadata_inode)) { path_completed = -1; /* remove the foreslash from the beginning * of the path we have at this point since * as now assembled it implies that the * unconnected dir parent is connected to * the fileset root directory. */ path_ptr++; } } if (gip_rc == FSCK_OK) /* indicate where to find the 1st char of the path just * assembled */ *addr_path_addr = path_ptr; return (gip_rc);}/***************************************************************************** * NAME: in_inode_data_check * * FUNCTION: Verify that the fields in the current inode which describe * inline data (that is, storage within the inode itself) do * not overlap. * * PARAMETERS: * msg_info_ptr - input - pointer to a record with information needed * to issue messages about the current inode * * NOTES: The data regarding inline data for the inode is stored in * the global aggregate record, fields in the this_inode record. * * RETURNS: * success: FSCK_OK * failure: something else */int in_inode_data_check(struct fsck_inode_record *inorecptr, struct fsck_ino_msg_info *msg_info_ptr){ int iidc_rc = FSCK_OK; int16_t size16; struct dinode an_inode; /* * if in-inode data (or description of data) overflows * this then the EA can NOT be inline */ size16 = sizeof (an_inode.di_inlinedata); if (agg_recptr->this_inode.in_inode_data_length > size16) { /* extra long inline data */ if (agg_recptr->this_inode.ea_inline) { /* conflict */ inorecptr->selected_to_rls = 1; inorecptr->inline_data_err = 1; inorecptr->clr_ea_fld = 1; agg_recptr->corrections_needed = 1; fsck_send_msg(fsck_INOINLINECONFLICT, fsck_ref_msg(msg_info_ptr->msg_inotyp), fsck_ref_msg(msg_info_ptr->msg_inopfx), msg_info_ptr->msg_inonum, fsck_longdata_and_otherinline); } if (agg_recptr->this_inode.acl_inline) { /* conflict */ inorecptr->selected_to_rls = 1; inorecptr->inline_data_err = 1; inorecptr->clr_acl_fld = 1; agg_recptr->corrections_needed = 1; fsck_send_msg(fsck_INOINLINECONFLICT, fsck_ref_msg(msg_info_ptr->msg_inotyp), fsck_ref_msg(msg_info_ptr->msg_inopfx), msg_info_ptr->msg_inonum, fsck_longdata_and_otherinline); } } else { if (agg_recptr->this_inode.ea_inline && agg_recptr->this_inode.acl_inline) { /* conflict */ inorecptr->clr_ea_fld = 1; inorecptr->clr_acl_fld = 1; agg_recptr->corrections_needed = 1; fsck_send_msg(fsck_INOINLINECONFLICT, fsck_ref_msg(msg_info_ptr->msg_inotyp), fsck_ref_msg(msg_info_ptr->msg_inopfx), msg_info_ptr->msg_inonum, fsck_longdata_and_otherinline); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -