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

📄 fsckino.c

📁 jfs 源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *   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 *//* 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; /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  *  * For message processing  *  *      defined in xchkdsk.c  */extern UniChar uni_message_parm[];extern UniChar *uni_msgprm;extern char *verbose_msg_ptr;extern char *Vol_Label; /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  *  * Device information.  *  *      defined in xchkdsk.c  */extern HFILE Dev_IOPort;extern uint32_t Dev_blksize;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: calculate_dasd_used * * FUNCTION: Calculate the cumulative amount of dasd used for each directory *           in the file system. * * PARAMETERS:  none * * RETURNS: *      success: FSCK_OK *      failure: something else */int calculate_dasd_used(){	int cdu_rc = FSCK_OK;	uint32_t ino_idx;	struct fsck_inode_record *this_inorec;	struct fsck_inode_record *this_child_inorec;	struct fsck_inode_record *this_parent_inorec;	struct fsck_inode_record *next_parent_inorec;	int aggregate_inode = 0;	int alloc_ifnull = 0;	int32_t this_level;	/*	 * In the first step we make a single pass on the inode records:	 *	 *     if the inode represents a file which is not an orphan then the	 *     number of blocks used by the file is added to the cummulative	 *     total for the parent inode.	 *	 *     if the inode represents a directory then we figure out the	 *     distance, in the fileset directory tree, between this inode and	 *     the root directory inode.	 */	cdu_rc = get_inorecptr_first(aggregate_inode, &ino_idx, &this_inorec);	if ((cdu_rc != FSCK_OK) || (this_inorec == NULL))		goto out;	while (ino_idx < FILESET_OBJECT_I) {		/*		 * not interesting until we get past the root inode		 * and the special fileset inodes.		 */		cdu_rc =		    get_inorecptr_next(aggregate_inode, &ino_idx, &this_inorec);		if ((cdu_rc != FSCK_OK) || (this_inorec == NULL))			goto out;	}	while (this_inorec != NULL) {		if ((!this_inorec->in_use) || this_inorec->selected_to_rls)			goto next_inode;		if (this_inorec->inode_type != directory_inode) {			/* it's a file */			if (this_inorec->parent_inonum == 0)	/* orphan */				goto next_inode;			cdu_rc = get_inorecptr(aggregate_inode, alloc_ifnull,					       this_inorec->parent_inonum,					       &this_parent_inorec);			if ((cdu_rc == FSCK_OK) && (this_parent_inorec == NULL))				cdu_rc = FSCK_INTERNAL_ERROR_63;			if (cdu_rc != FSCK_OK)				goto out;			this_parent_inorec->cumm_blocks +=			    this_inorec->cumm_blocks;			goto next_inode;		}		/* it's a directory */		if (this_inorec->dtree_level != -1)			/* distance already known */			goto next_inode;		if (this_inorec->parent_inonum == 0) {			/* it's an orphan */			this_inorec->dtree_level = 0;			if (this_inorec->dtree_level > agg_recptr->tree_height)				agg_recptr->tree_height =				    this_inorec->dtree_level;			goto next_inode;		}		/* it's not an orphan */		cdu_rc = get_inorecptr(aggregate_inode, alloc_ifnull,				       this_inorec->parent_inonum,				       &this_parent_inorec);		if ((cdu_rc == FSCK_OK) && (this_parent_inorec == NULL))			cdu_rc = FSCK_INTERNAL_ERROR_64;		if (cdu_rc != FSCK_OK)			goto out;		agg_recptr->treeStack = NULL;		cdu_rc = treeStack_push(this_inorec);		while (this_parent_inorec->dtree_level == -1) {			if (this_parent_inorec->parent_inonum == 0) {				/* orphan */				this_parent_inorec->dtree_level = 0;			} else {				/* not an orphan */				cdu_rc =				    get_inorecptr(aggregate_inode, alloc_ifnull,						  this_parent_inorec->						  parent_inonum,						  &next_parent_inorec);				if ((cdu_rc == FSCK_OK)				    && (next_parent_inorec == NULL))					cdu_rc = FSCK_INTERNAL_ERROR_65;				if (cdu_rc == FSCK_OK) {					/* located next parent's inode rec */					cdu_rc =					    treeStack_push(this_parent_inorec);					this_parent_inorec = next_parent_inorec;				}				if (cdu_rc != FSCK_OK)					goto out;			}		}		this_level = this_parent_inorec->dtree_level;		/*		 * this is the first known level number		 * (distance) in the chain of directories		 * from here to the root.		 */		while (agg_recptr->treeStack != NULL) {			this_level++;			cdu_rc = treeStack_pop(&this_child_inorec);			this_child_inorec->dtree_level = this_level;			if (this_child_inorec->dtree_level >			    agg_recptr->tree_height) {				agg_recptr->tree_height =				    this_child_inorec->dtree_level;			}		}	      next_inode:		cdu_rc =		    get_inorecptr_next(aggregate_inode, &ino_idx, &this_inorec);		if (cdu_rc != FSCK_OK)			goto out;	}	/*	 *	 * In the second step we make one pass on the inode records for each	 * level in the fileset directory tree, since we must accumulate the	 * dasd used values from the bottom up.	 *	 */	this_level = agg_recptr->tree_height;	while (this_level > 0) {		cdu_rc = get_inorecptr_first(aggregate_inode, &ino_idx,					     &this_inorec);		if (cdu_rc != FSCK_OK)			goto out;		while ((this_inorec != NULL) && (ino_idx < FILESET_OBJECT_I)) {			/*			 * not interesting until we get past the root inode			 * and the special fileset inodes.			 */			cdu_rc = get_inorecptr_next(aggregate_inode, &ino_idx,						    &this_inorec);			if (cdu_rc != FSCK_OK)				goto out;		}		while (this_inorec != NULL) {			if ((this_inorec->in_use)			    && (!this_inorec->selected_to_rls)			    && (this_inorec->inode_type == directory_inode)			    && (this_inorec->dtree_level == this_level)) {				/*				 * inode in use and not selected to release and				 * type directory and dtree level is a match				 */				cdu_rc =				    get_inorecptr(aggregate_inode, alloc_ifnull,						  this_inorec->parent_inonum,						  &this_parent_inorec);				if ((cdu_rc == FSCK_OK)				    && (this_parent_inorec == NULL))					cdu_rc = FSCK_INTERNAL_ERROR_66;				if (cdu_rc != FSCK_OK)					goto out;				this_parent_inorec->cumm_blocks +=				    this_inorec->cumm_blocks;			}			cdu_rc =			    get_inorecptr_next(aggregate_inode, &ino_idx,					       &this_inorec);			if (cdu_rc != FSCK_OK)				goto out;		}		this_level--;	}      out:	return (cdu_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;	}	/*

⌨️ 快捷键说明

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