⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fsckmeta.c

📁 在Linux内核从2.4升级到2.6时需要升级的软件包
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *   Copyright (c) International Business Machines Corp., 2000-2002 * *   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>#include <time.h>/* defines and includes common among the fsck.jfs modules */#include "xfsckint.h"#include "devices.h"#include "diskmap.h"#include "jfs_byteorder.h"#include "message.h"#include "super.h"#include "utilsubs.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; /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  *  * For message processing  *  *      defined in xchkdsk.c  */extern char *Vol_Label;/* VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV * * The following are internal to this file * */int backout_ait_part1(int);int backout_valid_agg_inode(int, uint32_t, struct fsck_ino_msg_info *);int first_ref_check_other_ait(void);int record_ait_part1_again(int);int record_other_ait(void);int rootdir_tree_bad(struct dinode *, int *);int validate_super(int);int validate_super_2ndaryAI(int);int verify_agg_fileset_inode(struct dinode *, uint32_t, int,			     struct fsck_ino_msg_info *);int verify_ait_inode(struct dinode *, int, struct fsck_ino_msg_info *);int verify_ait_part1(int);int verify_ait_part2(int);int verify_badblk_inode(struct dinode *, int, struct fsck_ino_msg_info *);int verify_bmap_inode(struct dinode *, int, struct fsck_ino_msg_info *);int verify_fs_super_ext(struct dinode *, struct fsck_ino_msg_info *, int *);int verify_log_inode(struct dinode *, int, struct fsck_ino_msg_info *);int verify_metadata_data(struct dinode *, uint32_t, struct fsck_inode_record *,			 struct fsck_ino_msg_info *);int verify_repair_fs_rootdir(struct dinode *, struct fsck_ino_msg_info *,			     int *);/* VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV  *//***************************************************************************** * NAME: agg_clean_or_dirty * * FUNCTION:  Compare the superblock state field (s_state) with fsck's *            conclusions about the current state (clean | dirty) of *            the aggregate.  If write access, attempt to update the *            state field if the superblock is incorrect.  If read-only, *            notify the caller if the superblock is incorrect. * * PARAMETERS:  none * * RETURNS: *      success: FSCK_OK *      failure: something else */int agg_clean_or_dirty(){	int acod_rc = FSCK_OK;	if (!agg_recptr->ag_dirty) {		/* aggregate is actually clean now */		/* announce this happy news */		fsck_send_msg(fsck_AGGCLN);		if (agg_recptr->processing_readonly) {			/* don't have write access */			if ((sb_ptr->s_state & FM_DIRTY) == FM_DIRTY) {				/* but isn't marked clean */				fsck_send_msg(fsck_AGGCLNNOTDRTY);			}		} else {			/* do have write access to the aggregate */			fsck_send_msg(fsck_ALLFXD);			sb_ptr->s_state = FM_CLEAN;			acod_rc = replicate_superblock();			if (acod_rc == FSCK_OK) {				fsck_send_msg(fsck_AGGMRKDCLN);			}		}	} else {		/* aggregate is actually dirty now */		fsck_send_msg(fsck_AGGDRTY);		if ((sb_ptr->s_state & FM_DIRTY) != FM_DIRTY) {			/* but isn't marked dirty */			if (agg_recptr->processing_readonly) {				/* don't have write access */				fsck_send_msg(fsck_AGGDRTYNOTCLN, Vol_Label);			} else {				/* do have write access to the aggregate */				/*				 * in keeping with the policy of protecting the system				 * from a potential panic due to a dirty file system,				 * if we have write access we'll mark the file system				 * dirty without asking permission.				 */				sb_ptr->s_state = FM_DIRTY;				acod_rc = replicate_superblock();				if (acod_rc == FSCK_OK) {					fsck_send_msg(fsck_AGGMRKDDRTY);				}			}		}	}	return (acod_rc);}/***************************************************************************** * NAME: backout_ait_part1 * * FUNCTION:  Unrecord, in the fsck workspace block map, all storage allocated *            to inodes in part 1 (inodes 0 through 15) of the specified *            (primary or secondary) aggregate inode table. * * PARAMETERS: *      which_ait  - input - the Aggregate Inode Table on which to perform *                           the function.  { fsck_primary | fsck_secondary } * * NOTES:  o The caller to this routine must ensure that the *           calls made by backout_ait_part1 to inode_get() *           will not require device I/O. *           That is, the caller must ensure that the aggregate *           inode extent containing part1 of the target AIT *           resides in the fsck inode buffer before calling *           this routine.  (See inode_get() for more info.) * * RETURNS: *      success: FSCK_OK *      failure: something else */int backout_ait_part1(int which_ait){	int baitp1_rc = FSCK_OK;	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_aggr_inode;	msg_info_ptr->msg_inotyp = fsck_metadata;	agg_recptr->inode_stamp = -1;	msg_info_ptr->msg_inonum = AGGREGATE_I;	baitp1_rc =	    backout_valid_agg_inode(which_ait, AGGREGATE_I, msg_info_ptr);	msg_info_ptr->msg_inonum = BMAP_I;	if (baitp1_rc == FSCK_OK) {		baitp1_rc =		    backout_valid_agg_inode(which_ait, BMAP_I, msg_info_ptr);		msg_info_ptr->msg_inonum = LOG_I;		if (baitp1_rc == FSCK_OK) {			baitp1_rc =			    backout_valid_agg_inode(which_ait, LOG_I,						    msg_info_ptr);			msg_info_ptr->msg_inonum = BADBLOCK_I;			if (baitp1_rc == FSCK_OK) {				baitp1_rc =				    backout_valid_agg_inode(which_ait,							    BADBLOCK_I,							    msg_info_ptr);			}		}	}	return (baitp1_rc);}/***************************************************************************** * NAME: backout_valid_agg_inode * * FUNCTION:  Unrecord, in the fsck workspace block map, storage allocated to *            the specified aggregate inode, assuming that all data structures *            associated with the inode are consistent.  (E.g., the B+ Tree *            is at least internally consistent.) * * PARAMETERS: *      which_ait     - input - the Aggregate Inode Table on which to perform *                              the function.  { fsck_primary | fsck_secondary } *      inoidx        - input - ordinal number of the inode (i.e., inode number *                              as an int32_t) *      msg_info_ptr  - input - pointer to a data area with data needed to *                              issue messages about the inode * * NOTES:  o The caller to this routine must ensure that the *           calls made by backout_ait_part1 to inode_get() *           will not require device I/O. *           That is, the caller must ensure that the aggregate *           inode extent containing part1 of the target AIT *           resides in the fsck inode buffer before calling *           this routine.  (See inode_get() for more info.) * * RETURNS: *      success: FSCK_OK *      failure: something else */int backout_valid_agg_inode(int which_ait, uint32_t inoidx,			    struct fsck_ino_msg_info *msg_info_ptr){	int bvai_rc = FSCK_OK;	int agg_inode = -1;	int alloc_ifnull = 0;	struct dinode *inoptr;	struct fsck_inode_record *inorecptr;	bvai_rc = inode_get(agg_inode, which_ait, inoidx, &inoptr);	if (bvai_rc != FSCK_OK) {		/* didn't get the inode  */		bvai_rc = FSCK_FAILED_REREAD_AGGINO;	} else {		/* got the inode */		bvai_rc =		    get_inorecptr(agg_inode, alloc_ifnull, inoidx, &inorecptr);		if ((bvai_rc == FSCK_OK) && (inorecptr == NULL)) {			bvai_rc = FSCK_INTERNAL_ERROR_22;			fsck_send_msg(fsck_INTERNALERROR, bvai_rc, 0, 0, 0);		} else if (bvai_rc == FSCK_OK) {			bvai_rc =			    unrecord_valid_inode(inoptr, inoidx, inorecptr,						 msg_info_ptr);		}	}	return (bvai_rc);}/***************************************************************************** * NAME: fatal_dup_check * * FUNCTION:  Determine whether any blocks are allocated to more than one *            aggregate metadata object.  (If so, the aggregate is too *            far gone for fsck to correct it, or even to analyze it with *            any confidence.) * * PARAMETERS:  none * * NOTES: *       This routine is called after all the following has been *       completed: *          - all metadata (aggregate and fileset) has been validated *          - all inode extents have been recorded *          - all fixed metadata has been recorded *          - the block map and inode map have been recorded * *       A similar check is done in validate_select_agg_inode_table *       when an apparently valid part of the table has been identified. * * RETURNS: *      success: FSCK_OK *      failure: something else */int fatal_dup_check(){	struct dupall_blkrec *dupblk_ptr;	int64_t first_in_range, this_blknum, last_blknum;	uint32_t range_size;	if (agg_recptr->dup_alloc_lst == NULL)		return FSCK_OK;	/* duplicate allocations detected during metadata validation */	dupblk_ptr = agg_recptr->dup_alloc_lst;	first_in_range = dupblk_ptr->first_blk;	last_blknum = dupblk_ptr->last_blk;	dupblk_ptr = dupblk_ptr->next;	while (dupblk_ptr != NULL) {		/* for all multiply allocated blocks */		this_blknum = dupblk_ptr->first_blk;		if (last_blknum != (this_blknum - 1)) {			range_size = last_blknum - first_in_range + 1;			fsck_send_msg(fsck_DUPBLKMDREF, range_size,				      (long long) first_in_range);			first_in_range = this_blknum;		}		last_blknum = dupblk_ptr->last_blk;		dupblk_ptr = dupblk_ptr->next;	}	range_size = last_blknum - first_in_range + 1;	fsck_send_msg(fsck_DUPBLKMDREF, range_size,		      (long long) first_in_range);	fsck_send_msg(fsck_DUPBLKMDREFS);	agg_recptr->ag_dirty = 1;	return (FSCK_DUPMDBLKREF);}/***************************************************************************** * NAME: first_ref_check_agg_metadata * * FUNCTION:  Determine whether the storage allocated for aggregate metadata *            includes a reference to any multiply-allocated aggregate blocks *            for which the first reference is still unresolved. * * PARAMETERS:  none * * RETURNS: *      success: FSCK_OK *      failure: something else */int first_ref_check_agg_metadata(){	int frcam_rc = FSCK_OK;	uint32_t ino_idx;	struct dinode *ino_ptr;	int aggregate_inode = -1;	/* going for aggregate inodes only */	int alloc_ifnull = 0;	int which_ait;	struct fsck_inode_record *inorec_ptr;	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_aggr_inode;	msg_info_ptr->msg_inotyp = fsck_metadata;	/*	 * check ait part 1 inodes for first references	 */	(agg_recptr->primary_ait_4part1) ? (which_ait = fsck_primary)	    : (which_ait = fsck_secondary);	/* try for the self inode */	ino_idx = AGGREGATE_I;	frcam_rc = inode_get(aggregate_inode, which_ait, ino_idx, &ino_ptr);	if (frcam_rc == FSCK_OK) {		/* got the self inode  */		msg_info_ptr->msg_inonum = ino_idx;		frcam_rc =		    get_inorecptr(aggregate_inode, alloc_ifnull, ino_idx,				  &inorec_ptr);		if ((frcam_rc == FSCK_OK) && (inorec_ptr == NULL)) {			frcam_rc = FSCK_INTERNAL_ERROR_25;			fsck_send_msg(fsck_INTERNALERROR, frcam_rc, 0, 0, 0);		} else if (frcam_rc == FSCK_OK) {			frcam_rc = first_ref_check_inode(ino_ptr, ino_idx,							 inorec_ptr,							 msg_info_ptr);		}	} else {		/* couldn't read the inode!		 * (We read it successfully a little while ago)		 */		frcam_rc = FSCK_FAILED_SELF_READ3;	}	if ((frcam_rc == FSCK_OK) && (agg_recptr->unresolved_1stref_count > 0)) {		/* no errors and still have 1st refs to resolve */		/* try for the blockmap inode */		ino_idx = BMAP_I;		frcam_rc =		    inode_get(aggregate_inode, which_ait, ino_idx, &ino_ptr);		if (frcam_rc == FSCK_OK) {			/* got the block map inode */			msg_info_ptr->msg_inonum = ino_idx;			frcam_rc =			    get_inorecptr(aggregate_inode, alloc_ifnull,					  ino_idx, &inorec_ptr);			if ((frcam_rc == FSCK_OK) && (inorec_ptr == NULL)) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -