📄 fsckino.c
字号:
/* * Copyright (C) International Business Machines Corp., 2000-2004 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <config.h>#include <string.h>/* defines and includes common among the fsck.jfs modules */#include "xfsckint.h"#include "jfs_byteorder.h"#include "jfs_unicode.h"#include "unicode_to_utf8.h" /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + * * superblock buffer pointer * * defined in xchkdsk.c */extern struct superblock *sb_ptr; /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + * * fsck aggregate info structure pointer * * defined in xchkdsk.c */extern struct fsck_agg_record *agg_recptr;extern int32_t Uni_Name_len;extern UniChar Uni_Name[];extern int32_t Str_Name_len;extern char Str_Name[];/***************************************************************************** * NAME: backout_ACL * * FUNCTION: Unrecord all storage allocated for the access control list * (ACL) of the current inode. * * PARAMETERS: * ino_ptr - input - pointer to the current inode * ino_recptr - input - pointer to an fsck inode record describing the * current inode * * RETURNS: * success: FSCK_OK * failure: something else */int backout_ACL(struct dinode *ino_ptr, struct fsck_inode_record *ino_recptr){ int bacl_rc = FSCK_OK; uint32_t block_count = 0; uint32_t extent_length; int64_t extent_address; int8_t extent_is_valid; /* * the following will be passed to extent_unrecord() which will * ignore them. */ int8_t is_EA = 0; int8_t is_ACL = 1; struct fsck_ino_msg_info *msg_info_ptr = NULL; /* * if the ACL is in an out-of-line extent, release the blocks * allocated for it. */ if (ino_ptr->di_acl.flag == DXD_EXTENT) { extent_length = lengthDXD(&(ino_ptr->di_acl)); extent_address = addressDXD(&(ino_ptr->di_acl)); bacl_rc = process_extent(ino_recptr, extent_length, extent_address, is_EA, is_ACL, msg_info_ptr, &block_count, &extent_is_valid, FSCK_UNRECORD); } /* * backout the blocks in the ACL extent from the running totals for * fileset and inode, but not for the object * represented by the object (because they were never added to that). */ agg_recptr->blocks_this_fset -= block_count; agg_recptr->this_inode.all_blks -= block_count; return (bacl_rc);}/***************************************************************************** * NAME: backout_EA * * FUNCTION: Unrecord all storage allocated for the extended attributes * (ea) of the current inode. * * PARAMETERS: * ino_ptr - input - pointer to the current inode * ino_recptr - input - pointer to an fsck inode record describing the * current inode * * RETURNS: * success: FSCK_OK * failure: something else */int backout_EA(struct dinode *ino_ptr, struct fsck_inode_record *ino_recptr){ int bea_rc = FSCK_OK; uint32_t block_count = 0; uint32_t extent_length; int64_t extent_address; int8_t extent_is_valid; /* * the following will be passed to extent_unrecord() which will * ignore them. */ int8_t is_EA = 1; int8_t is_ACL = 0; struct fsck_ino_msg_info *msg_info_ptr = NULL; /* * if the EA is in an out-of-line extent, release the blocks * allocated for it. */ if (ino_ptr->di_ea.flag == DXD_EXTENT) { extent_length = lengthDXD(&(ino_ptr->di_ea)); extent_address = addressDXD(&(ino_ptr->di_ea)); bea_rc = process_extent(ino_recptr, extent_length, extent_address, is_EA, is_ACL, msg_info_ptr, &block_count, &extent_is_valid, FSCK_UNRECORD); } /* * backout the blocks in the EA extent from the running totals for * fileset and inode, but not for the object * represented by the object (because they were never added to that). */ agg_recptr->blocks_this_fset -= block_count; agg_recptr->this_inode.all_blks -= block_count; return (bea_rc);}/***************************************************************************** * NAME: clear_ACL_field * * FUNCTION: Unrecord all storage allocated for the access control list * (ACL) of the current inode. Clear the inode ACL field to show * the inode owns no ACL. * * PARAMETERS: * ino_recptr - input - pointer to an fsck inode record describing the * current inode * ino_ptr - input - pointer to the current inode * * RETURNS: * success: FSCK_OK * failure: something else */int clear_ACL_field(struct fsck_inode_record *ino_recptr, struct dinode *ino_ptr){ int caf_rc = FSCK_OK; dxd_t *dxd_ptr; uint32_t block_count = 0; uint32_t extent_length; int64_t extent_address; int8_t extent_is_valid; /* * the following will be passed to extent_unrecord() which will * ignore them. */ int8_t is_EA = 0; int8_t is_ACL = -1; struct fsck_ino_msg_info *msg_info_ptr = NULL; /* locate the EA field in the inode */ dxd_ptr = &(ino_ptr->di_acl); /* * if the ACL is in an out-of-line extent, release the blocks * allocated for it. */ if ((dxd_ptr->flag == DXD_EXTENT) && (!ino_recptr->ignore_acl_blks) && (!ino_recptr->ignore_alloc_blks)) { /* out of line single extent and not flagged to ignore */ extent_length = lengthDXD(dxd_ptr); extent_address = addressDXD(dxd_ptr); caf_rc = process_extent(ino_recptr, extent_length, extent_address, is_EA, is_ACL, msg_info_ptr, &block_count, &extent_is_valid, FSCK_UNRECORD); ino_ptr->di_nblocks -= block_count; agg_recptr->blocks_for_acls -= block_count; } /* * Clear the ACL field */ if (caf_rc == FSCK_OK) { dxd_ptr->flag = DXD_CORRUPT; /* clear the data length */ DXDlength(dxd_ptr, 0); /* clear the data address */ DXDaddress(dxd_ptr, 0); agg_recptr->blocks_this_fset -= block_count; } return (caf_rc);}/***************************************************************************** * NAME: clear_EA_field * * FUNCTION: Unrecord all storage allocated for the extended attributes * (ea) of the current inode. Clear the inode ea field to show * the inode owns no ea. * * PARAMETERS: * ino_recptr - input - pointer to an fsck inode record describing the * current inode * ino_ptr - input - pointer to the current inode * * RETURNS: * success: FSCK_OK * failure: something else */int clear_EA_field(struct fsck_inode_record *ino_recptr, struct dinode *ino_ptr){ int cef_rc = FSCK_OK; dxd_t *dxd_ptr; uint32_t block_count = 0; uint32_t extent_length; int64_t extent_address; int8_t extent_is_valid; /* * the following will be passed to extent_unrecord() which will * ignore them. */ int8_t is_EA = -1; int8_t is_ACL = 0; struct fsck_ino_msg_info *msg_info_ptr = NULL; /* locate the EA field in the inode */ dxd_ptr = &(ino_ptr->di_ea); /* * if the EA is in an out-of-line extent, release the blocks * allocated for it. */ if ((dxd_ptr->flag == DXD_EXTENT) && (!ino_recptr->ignore_ea_blks) && (!ino_recptr->ignore_alloc_blks)) { /* out of line single extent and not flagged to ignore */ extent_length = lengthDXD(dxd_ptr); extent_address = addressDXD(dxd_ptr); cef_rc = process_extent(ino_recptr, extent_length, extent_address, is_EA, is_ACL, msg_info_ptr, &block_count, &extent_is_valid, FSCK_UNRECORD); agg_recptr->blocks_for_eas -= block_count; } /* * Clear the EA field */ if (cef_rc == FSCK_OK) { dxd_ptr->flag = 0; /* clear the data length */ DXDlength(dxd_ptr, 0); /* clear the data address */ DXDaddress(dxd_ptr, 0); ino_ptr->di_nblocks -= block_count; agg_recptr->blocks_this_fset -= block_count; } return (cef_rc);}/***************************************************************************** * NAME: display_path * * FUNCTION: Issue a message to display the given inode path. * * PARAMETERS: * inoidx - input - ordinal number of the inode as an integer * inopfx - input - index (into message catalog) of prefix for * inode number when displayed in message * { A | <blank> } * ino_parent - input - the inode number for the (parent) directory * whose entry to the current inode is described * by the contents of inopath. * inopath - input - pointer to the UniCharacter path which is * to be displayed. * ino_recptr - input - pointer to an fsck inode record describing the * current inode * * RETURNS: * success: FSCK_OK * failure: something else */int display_path(uint32_t inoidx, int inopfx, uint32_t ino_parent, char *inopath, struct fsck_inode_record *ino_recptr){ int dip_rc = FSCK_OK; if ((!ino_recptr->unxpctd_prnts) || (!(ino_recptr->inode_type == directory_inode))) { /* not directory w/ mult parents */ if (ino_recptr->inode_type == directory_inode) { fsck_send_msg(fsck_INOPATHOK, fsck_ref_msg(fsck_directory), fsck_ref_msg(inopfx), inoidx, inopath); } else if (ino_recptr->inode_type == char_special_inode) { fsck_send_msg(fsck_INOPATHOK, fsck_ref_msg(fsck_char_special), fsck_ref_msg(inopfx), inoidx, inopath); } else if (ino_recptr->inode_type == block_special_inode) { fsck_send_msg(fsck_INOPATHOK, fsck_ref_msg(fsck_block_special), fsck_ref_msg(inopfx), inoidx, inopath); } else if (ino_recptr->inode_type == FIFO_inode) { fsck_send_msg(fsck_INOPATHOK, fsck_ref_msg(fsck_FIFO), fsck_ref_msg(inopfx), inoidx, inopath); } else if (ino_recptr->inode_type == SOCK_inode) { fsck_send_msg(fsck_INOPATHOK, fsck_ref_msg(fsck_SOCK), fsck_ref_msg(inopfx), inoidx, inopath); } else { /* regular file */ fsck_send_msg(fsck_INOPATHOK, fsck_ref_msg(fsck_file), fsck_ref_msg(inopfx), inoidx, inopath); } } else { /* else a directory w/ multiple parents */ if (ino_parent == ino_recptr->parent_inonum) { /* expected parent */ fsck_send_msg(fsck_INOPATHCRCT, inopath, fsck_ref_msg(inopfx), inoidx); } else { /* this is an illegal hard link */ fsck_send_msg(fsck_INOPATHBAD, fsck_ref_msg(fsck_directory), fsck_ref_msg(inopfx), inoidx, inopath); } } return (dip_rc);}/***************************************************************************** * NAME: display_paths * * FUNCTION: Display all paths to the specified inode. * * PARAMETERS: * inoidx - input - ordinal number of the inode as an integer * ino_recptr - 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 display_paths(uint32_t inoidx, struct fsck_inode_record *ino_recptr, struct fsck_ino_msg_info *msg_info_ptr){ int dips_rc = FSCK_OK; int intermed_rc; uint32_t this_parent = 0; struct fsck_inode_ext_record *this_ext = NULL; char *this_path_ptr; char **this_path_ptr_ptr; struct fsck_inode_record *parent_inorecptr; int a_path_displayed = 0; this_path_ptr_ptr = &this_path_ptr; if (inoidx == 2) { /* it's the root directory */ intermed_rc = get_path(inoidx, this_parent, this_path_ptr_ptr, ino_recptr); a_path_displayed = -1; dips_rc = display_path(inoidx, msg_info_ptr->msg_inopfx, this_parent, this_path_ptr, ino_recptr); goto out; } else if (ino_recptr->parent_inonum == 0) goto out; /* at least one parent was observed */ /* * if this is a directory with illegal hard links then the * inode number in the fsck inode record is the one stored in * the inode on disk. This routine displays only messages * for parents observed by fsck. */ if ((ino_recptr->inode_type == directory_inode) && (ino_recptr->unxpctd_prnts)) { /* dir with multiple parents */ this_ext = ino_recptr->ext_rec; while ((this_ext != NULL) && (this_ext->ext_type != parent_extension)) { this_ext = this_ext->next; } if (this_ext == NULL) { /* something is terribly wrong! */ dips_rc = FSCK_INTERNAL_ERROR_1; } } else { /* not a dir with multiple parents */ /* * the 1st parent observed is in the inode record. Any * others are in extension records. */ this_parent = ino_recptr->parent_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 != FSCK_OK) { dips_rc = intermed_rc;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -