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

📄 fsckxtre.c

📁 jfs 源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	last_key = -1;	for (xadidx = XTENTRYSTART;	     ((xadidx < xtpg_ptr->header.nextindex) &&	      (xpie_rc == FSCK_OK) && (!ino_recptr->ignore_alloc_blks));	     xadidx++) {		xad_ptr = &(xtpg_ptr->xad[xadidx]);		if ((xad_ptr->flag & flag_mask)) {			/* bad flag value */			ino_recptr->ignore_alloc_blks = 1;			goto out;		}		this_key = offsetXAD(xad_ptr);		if (this_key <= last_key) {			/* these keys MUST ascend */			ino_recptr->ignore_alloc_blks = 1;			if (desired_action == FSCK_RECORD_DUPCHECK) {				/* first detection */				fsck_send_msg(fsck_BADKEYS,					      fsck_ref_msg(msg_info_ptr->msg_inotyp),					      fsck_ref_msg(msg_info_ptr->msg_inopfx),					      msg_info_ptr->msg_inonum,					      7);			}			goto out;		}		/* key looks ok from here */		last_key = this_key;		ext_addr = addressXAD(xad_ptr);		ext_length = lengthXAD(xad_ptr);		xpie_rc = process_extent(ino_recptr, ext_length, ext_addr,					 is_EA, is_ACL, msg_info_ptr,					 &adjusted_length, &ext_ok,					 desired_action);		if ((xpie_rc != FSCK_OK) || !ext_ok)			goto out;		/* extent is good */		if ((desired_action == FSCK_RECORD) ||		    (desired_action == FSCK_RECORD_DUPCHECK)) {			agg_recptr->blocks_this_fset += adjusted_length;			agg_recptr->this_inode.all_blks += adjusted_length;		} else if (desired_action == FSCK_UNRECORD) {			agg_recptr->blocks_this_fset -= adjusted_length;			agg_recptr->this_inode.all_blks -= adjusted_length;		}		xpie_rc = treeQ_get_elem(&new_Qelptr);		if (xpie_rc != FSCK_OK)			goto out;		/* got a queue element */		new_Qelptr->node_level = Q_elptr->node_level + 1;		new_Qelptr->node_addr = ext_addr;		PXDaddress(&(new_Qelptr->node_pxd), ext_addr);		PXDlength(&(new_Qelptr->node_pxd), ext_length);		new_Qelptr->node_first_offset = this_key;		xpie_rc = treeQ_enqueue(new_Qelptr);	}      out:	return (xpie_rc);}/***************************************************************************** * NAME: xTree_process_leaf_extents * * FUNCTION:  Helper routine for xTree_processing * * PARAMETERS: *      xtpg_ptr        - input - pointer to the leaf node in an fsck buffer *      inorecptr       - input - pointer to the fsck inode record describing *                                the inode in which the xTree is rooted *      Q_elptr         - input - address of an fsck Q element pointer *                                describing the leaf *      msg_info_ptr    - input - pointer to data needed for messages about the *                                inode in which the xTree is rooted *      dense_file      - input - !0 => the xTree describes a dense file *                                 0 => the xTree describes a file which may *                                      be sparse *      desired_action  - input - { FSCK_RECORD | FSCK_RECORD_DUPCHECK | *                                  FSCK_UNRECORD | FSCK_QUERY } * * RETURNS: *      success: FSCK_OK *      failure: something else */int xTree_process_leaf_extents(xtpage_t * xtpg_ptr,			       struct fsck_inode_record *ino_recptr,			       struct treeQelem *Q_elptr,			       struct fsck_ino_msg_info *msg_info_ptr,			       int8_t dense_file, int desired_action){	int xple_rc = FSCK_OK;	int64_t last_key, this_key;	uint32_t xadidx;	uint32_t ext_length, adjusted_length;	int64_t ext_addr;	int8_t ext_ok;	int8_t is_EA = 0;	int8_t is_ACL = 0;	xad_t *xad_ptr;	uint32_t ext_pages;	uint8_t flag_mask;	flag_mask =	    ~(XAD_NEW | XAD_EXTENDED | XAD_COMPRESSED | XAD_NOTRECORDED |	      XAD_COW);	last_key = -1;	for (xadidx = XTENTRYSTART;	     ((xadidx < xtpg_ptr->header.nextindex) &&	      (xple_rc == FSCK_OK) && (!ino_recptr->ignore_alloc_blks));	     xadidx++) {		xad_ptr = &(xtpg_ptr->xad[xadidx]);		if ((xad_ptr->flag & flag_mask)) {			/* bad flag value */			ino_recptr->ignore_alloc_blks = 1;		}		this_key = offsetXAD(xad_ptr);		if ((last_key != -1) && (!ino_recptr->ignore_alloc_blks)) {			/* not the first key */			if (this_key <= last_key) {				/* these keys MUST ascend */				ino_recptr->ignore_alloc_blks = 1;				if (desired_action == FSCK_RECORD_DUPCHECK) {					/* first detection */					fsck_send_msg(fsck_BADKEYS,						      fsck_ref_msg(msg_info_ptr->msg_inotyp),						      fsck_ref_msg(msg_info_ptr->msg_inopfx),						      msg_info_ptr->msg_inonum,						      8);				}				goto out;			}			/* the keys do ascend */			if ((dense_file)			    && (this_key != (last_key + 1))) {				/* a dense file with a gap! */				ino_recptr->ignore_alloc_blks = 1;				if (desired_action == FSCK_RECORD_DUPCHECK) {					/* first detection */					fsck_send_msg(fsck_BADINOINTERNGAP,						      fsck_ref_msg(msg_info_ptr->msg_inopfx),						      msg_info_ptr->msg_inonum,						      msg_info_ptr->msg_inonum);				}				goto out;			}		}		ext_addr = addressXAD(xad_ptr);		ext_length = lengthXAD(xad_ptr);		last_key = this_key + ext_length - 1;		agg_recptr->this_inode.data_size =		    (last_key + 1) * sb_ptr->s_bsize;		/*		 * all extents (except the very last one for the inode) must		 * be in full (4096 byte) pages.		 */		ext_pages = ext_length >> agg_recptr->log2_blksperpg;		if ((ext_length != (ext_pages << agg_recptr->log2_blksperpg))		    && (!(ino_recptr->badblk_inode))) {			/*			 * this one is an odd size and isn't			 * owned by the bad block inode			 */			if (xadidx == (xtpg_ptr->header.nextindex - 1)) {				/*				 * this is the last extent for the node				 * and might be the last for the inode				 */				Q_elptr->last_ext_uneven = -1;			} else {				/* not the last extent for the xtpage */				ino_recptr->ignore_alloc_blks = 1;				if (desired_action == FSCK_RECORD_DUPCHECK) {					/* first detection */					fsck_send_msg					    (fsck_BADINOODDINTRNEXT,					     fsck_ref_msg(msg_info_ptr->msg_inotyp),					     fsck_ref_msg(msg_info_ptr->msg_inopfx),					     msg_info_ptr->msg_inonum,					     (long long) this_key,					     ext_length);				}				goto out;			}		}		xple_rc = process_extent(ino_recptr, ext_length, ext_addr,					 is_EA, is_ACL, msg_info_ptr,					 &adjusted_length, &ext_ok,					 desired_action);		if ((desired_action == FSCK_RECORD)		    || (desired_action == FSCK_RECORD_DUPCHECK)) {			agg_recptr->blocks_this_fset += adjusted_length;			agg_recptr->this_inode.all_blks += adjusted_length;			agg_recptr->this_inode.data_blks += adjusted_length;		} else if (desired_action == FSCK_UNRECORD) {			agg_recptr->blocks_this_fset -= adjusted_length;			agg_recptr->this_inode.all_blks -= adjusted_length;			agg_recptr->this_inode.data_blks -= adjusted_length;		}	}      out:	return (xple_rc);}/***************************************************************************** * NAME: xTree_processing * * FUNCTION: Validate the structure of the xTree rooted in the given inode *           and perform the desired_action on the nodes in the xTree. *           Stop processing the xTree if and when any symptom of corruption *           is detected. * * PARAMETERS: *      inoptr        - input - pointer to the inode in which the xTree is *                                   rooted *      inoidx        - input - ordinal number of the inode *      inorecptr    - input - pointer to the fsck inode record describing *                                   the inode *      msg_info_ptr    - input - pointer to data needed for messages about *                                        the inode *      desired_action  - input - { FSCK_RECORD | FSCK_RECORD_DUPCHECK | *                                  FSCK_UNRECORD | FSCK_QUERY | *                                  FSCK_FSIM_RECORD_DUPCHECK  | *                                  FSCK_FSIM_UNRECORD | FSCK_FSIM_QUERY } * * RETURNS: *      success: FSCK_OK *      failure: something else */int xTree_processing(struct dinode *inoptr,		     uint32_t inoidx,		     struct fsck_inode_record *inorecptr,		     struct fsck_ino_msg_info *msg_info_ptr, int desired_action){	int xp_rc = FSCK_OK;	int8_t old_ignore_alloc_blks = 0;	int ixpxd_unequal = 0;	int is_root = -1;	int not_fsim_tree = -1;	struct fsck_Xtree_info xtinfo;	struct fsck_Xtree_info *xtiptr;	xtiptr = &xtinfo;	xtiptr->this_Qel = NULL;	xtiptr->next_Qel = NULL;	xtiptr->last_level = -1;	/* -1 so the root will be recognized					 * as 1st node in level 0					 */	xtiptr->dense_file = 0;	xtiptr->leaf_seen = 0;	if (!(inoptr->di_mode & ISPARSE)) {		xtiptr->dense_file = -1;	}	switch (desired_action) {	case (FSCK_FSIM_RECORD_DUPCHECK):		not_fsim_tree = 0;		desired_action = FSCK_RECORD_DUPCHECK;		break;	case (FSCK_FSIM_UNRECORD):		not_fsim_tree = 0;		desired_action = FSCK_UNRECORD;		break;	case (FSCK_FSIM_QUERY):		not_fsim_tree = 0;		desired_action = FSCK_QUERY;		break;	default:		break;	}	if (ISDIR(inoptr->di_mode))		xtiptr->xtp_ptr = (xtpage_t *) & (inoptr->di_dirtable);	else		xtiptr->xtp_ptr = (xtpage_t *) & (inoptr->di_btroot);	if ((!ISDIR(inoptr->di_mode)	     && (xtiptr->xtp_ptr->header.maxentry != XTROOTINITSLOT)	     && (xtiptr->xtp_ptr->header.maxentry != XTROOTMAXSLOT))	    || (ISDIR(inoptr->di_mode)		&& (xtiptr->xtp_ptr->header.maxentry != XTROOTINITSLOT_DIR))) {		/* bad maxentry field */		inorecptr->ignore_alloc_blks = 1;		if (desired_action == FSCK_RECORD_DUPCHECK) {			/* not reported yet */			fsck_send_msg(fsck_BADINOOTHR, "45",				      fsck_ref_msg(msg_info_ptr->msg_inotyp),				      fsck_ref_msg(msg_info_ptr->msg_inopfx),				      msg_info_ptr->msg_inonum);		}		/* end not reported yet */		goto out;	}	if (xtiptr->xtp_ptr->header.nextindex >	    xtiptr->xtp_ptr->header.maxentry) {		/* bad nextindex field */		inorecptr->ignore_alloc_blks = 1;		if (desired_action == FSCK_RECORD_DUPCHECK) {			/* not reported yet */			fsck_send_msg(fsck_BADINOOTHR, "46",				      fsck_ref_msg(msg_info_ptr->msg_inotyp),				      fsck_ref_msg(msg_info_ptr->msg_inopfx),				      msg_info_ptr->msg_inonum);		}		goto out;	}	if (xtiptr->xtp_ptr->header.nextindex <= XTENTRYSTART)		goto out;	/* data length > 0 */	if (desired_action != FSCK_RECORD_DUPCHECK) {		/* not the first pass */		/*		 * The first time through we stopped processing allocated		 * blocks if and when we discovered the tree to be corrupt.		 * On a 2nd pass we want to stop at the same place.		 */		if (inorecptr->ignore_alloc_blks) {			/* the bit is on */			old_ignore_alloc_blks = -1;			inorecptr->ignore_alloc_blks = 0;		}	}	xtiptr->this_key = offsetXAD(&(xtiptr->xtp_ptr->xad[XTENTRYSTART]));	if (xtiptr->dense_file && (xtiptr->this_key != ((int64_t) 0))) {		/* a dense file with a gap at the front */		inorecptr->ignore_alloc_blks = 1;		if (desired_action == FSCK_RECORD_DUPCHECK) {			/* not reported yet */			fsck_send_msg(fsck_BADINOFRONTGAP,				      fsck_ref_msg(msg_info_ptr->msg_inopfx),				      msg_info_ptr->msg_inonum);		}		goto release;	}	xp_rc = treeQ_get_elem(&xtiptr->this_Qel);	if (xp_rc != FSCK_OK)		goto out;	xtiptr->this_Qel->node_level = 0;	if (xtiptr->xtp_ptr->header.flag & BT_LEAF) {		/* root leaf */		if (not_fsim_tree) {			/* not the FileSet Inode Map tree */			xp_rc = xTree_process_leaf_extents			    (xtiptr->xtp_ptr, inorecptr, xtiptr->this_Qel,			     msg_info_ptr, xtiptr->dense_file, desired_action);		}		xtiptr->xad_ptr =		    &(xtiptr->		      xtp_ptr->xad[xtiptr->xtp_ptr->header.nextindex - 1]);		agg_recptr->this_inode.data_size =		    (int64_t) (offsetXAD(xtiptr->xad_ptr) +			       lengthXAD(xtiptr->xad_ptr)) * sb_ptr->s_bsize;		/*		 * By definition, a root-leaf is the last leaf		 * for the inode

⌨️ 快捷键说明

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