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

📄 fsckino.c

📁 jfs 源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	msg_info_ptr->msg_dxdtyp = fsck_objcontents;	/*	 * examine the data field	 */	if (dxd_ptr->flag == 0)		goto out;	/* Work around bug that used to clear the DXD_INDEX bit */	dxd_ptr->flag |= DXD_INDEX;	/*	 * to be valid, it has to be a B-tree node,	 * either root-leaf or root-internal	 */	if ((dxd_ptr->flag != (DXD_INDEX | BT_ROOT | BT_LEAF))	    && (dxd_ptr->flag != (DXD_INDEX | BT_ROOT | BT_INTERNAL))) {		/*		 * the data root is not valid...the info cannot be trusted		 */		inorecptr->selected_to_rls = 1;		inorecptr->ignore_alloc_blks = 1;		agg_recptr->corrections_needed = 1;		fsck_send_msg(fsck_BADINODXDFLDD,			      fsck_ref_msg(msg_info_ptr->msg_inotyp),			      fsck_ref_msg(msg_info_ptr->msg_inopfx),			      msg_info_ptr->msg_inonum,			      fsck_ref_msg(msg_info_ptr->msg_dxdtyp));		goto out;	}	/*	 * figure out how much space the root occupies in the inode itself	 */	agg_recptr->this_inode.in_inode_data_length =	    (DTROOTMAXSLOT - 1) * sizeof (struct dtslot);	/*	 * The root actually starts 32 bytes (aka the length	 * of 1 slot) before the boundary.	 * the 1st slot is really the header	 */	/*	 * process the xtree if the new directory table is supported	 * and if the directory table data is not inline (index > 14)	 */	if (sb_ptr->s_flag & JFS_DIR_INDEX)		inorecptr->check_dir_index = 1;	if ((sb_ptr->s_flag & JFS_DIR_INDEX) &&	    inoptr->di_next_index > MAX_INLINE_DIRTABLE_ENTRY + 1) {		/*		 * validate the tree contents and record the extents it		 * describes until and unless the tree is found to be corrupt		 */		vdd_rc =		    xTree_processing(inoptr, inoidx, inorecptr, msg_info_ptr,				     FSCK_RECORD_DUPCHECK);		if (vdd_rc < FSCK_OK)			goto out;	}	/* 	 * Check an error bit to see if there was something	 * wrong but non-fatal with xTree_processing.  If	 * so, reset the bit to give dTree_processing a	 * clean slate to start with.  Set a flag to 	 * indicate that the directory index table is to be rebuilt.	 */	if (inorecptr->ignore_alloc_blks) {		inorecptr->check_dir_index = 0;		inorecptr->rebuild_dirtable = 1;		inorecptr->ignore_alloc_blks = 0;		inorecptr->selected_to_rls = 0;		agg_recptr->corrections_needed = 1;		xt_ignore_alloc_blks = 1;	}	/*	 * validate the tree contents and record the extents it	 * describes until and unless the tree is found to be corrupt	 */	dtree_rc =	    dTree_processing(inoptr, inoidx, inorecptr, msg_info_ptr,			     FSCK_RECORD_DUPCHECK);	if (dtree_rc < FSCK_OK)		goto dtree_out;	if (inorecptr->ignore_alloc_blks) {		/* the tree info can't be used */		/*		 * reverse the notations made when recording the extents		 * for the tree.  Again, stop when the point of corruption		 * is found since that's where the recording process was		 * stopped.		 */		intermed_rc =		    dTree_processing(inoptr, inoidx, inorecptr, msg_info_ptr,				     FSCK_UNRECORD);		if (intermed_rc < 0) {			dtree_rc = intermed_rc;			goto dtree_out;		}		if (intermed_rc != FSCK_OK) {			if (dtree_rc == FSCK_OK) {				dtree_rc = intermed_rc;			}		}		if (!inorecptr->ignore_ea_blks) {			intermed_rc = backout_EA(inoptr, inorecptr);			if (intermed_rc < 0) {				dtree_rc = intermed_rc;				goto dtree_out;			}			if (intermed_rc != FSCK_OK) {				if (dtree_rc == FSCK_OK) {					dtree_rc = intermed_rc;				}			}			if (!inorecptr->ignore_acl_blks) {				intermed_rc = backout_ACL(inoptr, inorecptr);				if (intermed_rc < 0) {					dtree_rc = intermed_rc;					goto dtree_out;				}				if (intermed_rc != FSCK_OK) {					if (dtree_rc == FSCK_OK) {						dtree_rc = intermed_rc;					}				}			}		}	}	if ((sb_ptr->s_flag & JFS_DIR_INDEX) &&	    (inoptr->di_next_index > MAX_INLINE_DIRTABLE_ENTRY + 1) &&	    (inorecptr->ignore_alloc_blks || inorecptr->rebuild_dirtable)) {		/*		 * ignore_alloc_blks needs to exactly reflect the results		 * of the xTree_processing step		 */		save_ignore_alloc_blks = inorecptr->ignore_alloc_blks;		inorecptr->ignore_alloc_blks = xt_ignore_alloc_blks;		/*		 * reverse the notations made when recording the		 * extents for the tree.  Again, stop when the point		 * of corruption is found since that's where the		 * recording process was stopped.		 */		intermed_rc =		    xTree_processing(inoptr, inoidx, inorecptr,				     msg_info_ptr, FSCK_UNRECORD);		if (intermed_rc < 0) {			vdd_rc = intermed_rc;			goto out;		}		if (intermed_rc != FSCK_OK) {			if (vdd_rc == FSCK_OK) {				vdd_rc = intermed_rc;			}		}		inorecptr->ignore_alloc_blks = save_ignore_alloc_blks;		/*		 * If we don't fix di_nblocks now, the inode will be		 * thrown away (even if dtree is good).		 */		inoptr->di_nblocks = agg_recptr->this_inode.all_blks;	}      dtree_out:	/*	 * return the worse of the rc's for xtree and dtree processing	 */	if (dtree_rc != FSCK_OK) {		vdd_rc = dtree_rc;	}      out:	return (vdd_rc);}/***************************************************************************** * NAME: validate_EA * * FUNCTION: Determine whether the structures in the specified inode to *           describe ea data owned by the inode are consistent and (as *           far as fsck can tell) correct. * * PARAMETERS: *      inoptr        - input - pointer to the current inode *      inoidx        - input - ordinal number of the inode as an integer *      inorecptr     - 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 validate_EA(struct dinode *inoptr, uint32_t inoidx,		struct fsck_inode_record *inorecptr,		struct fsck_ino_msg_info *msg_info_ptr){	int vea_rc = FSCK_OK;	int intermed_rc = FSCK_OK;	dxd_t *dxd_ptr;	uint32_t recorded_length, shortest_valid, longest_valid;	uint32_t ext_length;	int64_t ext_byte_length;	int64_t ext_address = 0;	int8_t extent_is_valid = 0;	int8_t ea_format_bad = 0;	uint16_t size16;	struct dinode an_inode;	unsigned long eafmt_error = 0;	dxd_ptr = &(inoptr->di_ea);	msg_info_ptr->msg_dxdtyp = fsck_EA;	if (dxd_ptr->flag == 0)		goto out;	/* there is an EA for this inode */	if ((dxd_ptr->flag != DXD_EXTENT) && (dxd_ptr->flag != DXD_INLINE)) {		/* not a single extent AND not inline */		fsck_send_msg(fsck_BADINODXDFLDD,			      fsck_ref_msg(msg_info_ptr->msg_inotyp),			      fsck_ref_msg(msg_info_ptr->msg_inopfx),			      msg_info_ptr->msg_inonum,			      fsck_ref_msg(msg_info_ptr->msg_dxdtyp));		inorecptr->clr_ea_fld = 1;		inorecptr->ignore_ea_blks = 1;		agg_recptr->corrections_needed = 1;		goto out;	}	if (dxd_ptr->flag == DXD_INLINE) {		/* EA is inline  */		size16 = sizeof (an_inode.di_inlineea);		agg_recptr->this_inode.ea_inline = 1;		agg_recptr->this_inode.inline_ea_length = dxd_ptr->size;		agg_recptr->this_inode.inline_ea_offset =		    (uint16_t) addressDXD(dxd_ptr);		if ((dxd_ptr->size == 0)		    || (dxd_ptr->size >			(size16 - agg_recptr->this_inode.inline_ea_offset))) {			/*			 * the length extends			 * beyond the end of the inode			 */			fsck_send_msg(fsck_BADINODXDFLDL,				      fsck_ref_msg(msg_info_ptr->msg_inotyp),				      fsck_ref_msg(msg_info_ptr->msg_inopfx),				      msg_info_ptr->msg_inonum,				      fsck_ref_msg(msg_info_ptr->msg_dxdtyp));			inorecptr->clr_ea_fld = 1;			agg_recptr->corrections_needed = 1;		} else {			/* the inline ea has a valid length.			 * verify its format. */			vea_rc =			    jfs_ValidateFEAList((struct FEALIST *)						&(inoptr->di_inlineea),						dxd_ptr->size, &eafmt_error);			if ((vea_rc != FSCK_OK) || (eafmt_error != 0)) {				/* ea format is bad */				ea_format_bad = -1;			}		}	} else {		/* else the EA is a single extent */		ext_length = lengthDXD(dxd_ptr);		shortest_valid = (ext_length - 1) * sb_ptr->s_bsize + 1;		longest_valid = ext_length * sb_ptr->s_bsize;		if ((ext_length == 0) || (dxd_ptr->size < shortest_valid)		    || (dxd_ptr->size > longest_valid)) {			/* invalid length */			fsck_send_msg(fsck_BADINODXDFLDL,				      fsck_ref_msg(msg_info_ptr->msg_inotyp),				      fsck_ref_msg(msg_info_ptr->msg_inopfx),				      msg_info_ptr->msg_inonum,				      fsck_ref_msg(msg_info_ptr->msg_dxdtyp));			extent_is_valid = 0;			inorecptr->ignore_ea_blks = 1;		} else {			/* length and size might be ok */			agg_recptr->this_inode.ea_blks = ext_length;			ext_address = addressDXD(dxd_ptr);			vea_rc =			    process_extent(inorecptr, ext_length, ext_address,					   -1, 0, msg_info_ptr,					   &recorded_length, &extent_is_valid,					   FSCK_RECORD_DUPCHECK);			/*			 * add the blocks in the EA extent to the running			 * totals for the filese and inode, but not for the			 * object represented by the object.			 */			agg_recptr->blocks_this_fset += recorded_length;			agg_recptr->this_inode.all_blks += recorded_length;		}		if (!extent_is_valid) {			inorecptr->clr_ea_fld = 1;			agg_recptr->corrections_needed = 1;			goto out;		}		/* the extent looks ok so need to check ea data structure */		ext_byte_length = ext_length * sb_ptr->s_bsize;		if (ext_byte_length > agg_recptr->ea_buf_length) {			/* extra large ea  -- can't check it */			inorecptr->cant_chkea = 1;			agg_recptr->warning_pending = 1;			goto out;		}		/* regular size ea */		intermed_rc =		    ea_get(ext_address, ext_byte_length, agg_recptr->ea_buf_ptr,			   &(agg_recptr->ea_buf_length),			   &(agg_recptr->ea_buf_data_len),			   &(agg_recptr->ea_agg_offset));		if (intermed_rc != FSCK_OK) {			fsck_send_msg(fsck_BADINODXDFLDO,				      fsck_ref_msg(msg_info_ptr->msg_inotyp),				      fsck_ref_msg(msg_info_ptr->msg_inopfx),				      msg_info_ptr->msg_inonum,				      fsck_ref_msg(msg_info_ptr->msg_dxdtyp));			inorecptr->clr_ea_fld = 1;			agg_recptr->corrections_needed = 1;			goto out;		}		/* the ea has been read into the regular buffer */		vea_rc = jfs_ValidateFEAList((struct FEALIST *)					     agg_recptr->ea_buf_ptr,					     dxd_ptr->size, &eafmt_error);		if ((vea_rc != FSCK_OK) || (eafmt_error != 0)) {			/* ea format is bad */			ea_format_bad = -1;		}	}      out:	if (ea_format_bad) {		/* bad ea but haven't notified anyone */		fsck_send_msg(fsck_EAFORMATBAD,			      fsck_ref_msg(msg_info_ptr->msg_inotyp),			      fsck_ref_msg(msg_info_ptr->msg_inopfx),			      msg_info_ptr->msg_inonum);		inorecptr->clr_ea_fld = 1;		agg_recptr->corrections_needed = 1;		vea_rc = FSCK_OK;	}	return (vea_rc);}/***************************************************************************** * NAME: validate_record_fileset_inode * * FUNCTION:  Determine whether structures in and/or rooted in the specified *            fileset owned inode are consistent and (as far as fsck can tell) *            correct.  Record, in the fsck workspace block map, all storage *            allocated to the inode. * * PARAMETERS: *      inonum            - input - ordinal number of the inode in the *                                  internal JFS format *      inoidx            - input - ordinal number of the inode as an integer *      inoptr            - input - pointer to the current inode *      ino_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 validate_record_fileset_inode(uint32_t inonum, uint32_t inoidx,				  struct dinode *inoptr,				  struct fsck_ino_msg_info				  *ino_msg_info_ptr){	int vrfi_rc = FSCK_OK;	int intermed_rc = FSCK_OK;	struct fsck_inode_record *inorecptr;	int8_t bad_size = 0;	int aggregate_inode = 0;	int alloc_ifnull = -1;	int64_t min_size, max_size;	int16_t size16;	int8_t dinode_sect4_avail = 0;	struct dinode an_inode;	ino_msg_info_ptr->msg_inonum = inonum;	vrfi_rc =	    get_inorecptr(aggregate_inode, alloc_ifnull, inoidx, &inorecptr);	if (vrfi_rc != FSCK_OK)		goto out;	inorecptr->in_use = 1;	if (!(inode_type_recognized(inoptr))) {		/* bad type */		inorecptr->inode_type = unrecognized_inode;		ino_msg_info_ptr->msg_inotyp = fsck_file;		inorecptr->selected_to_rls = 1;		inorecptr->ignore_alloc_blks = 1;		/* no matter what the user		 * approves or disapproves, we aren't		 * going to even look to see which		 * blocks are allocated to this inode		 * (except for the blocks it occupies		 * itself)		 */		agg_recptr->corrections_needed = 1;		fsck_send_msg(fsck_BADINOTYP,			      fsck_ref_msg(ino_msg_info_ptr->msg_inopfx),			      ino_msg_info_ptr->msg_inonum);		goto out;	}	/* else type is recognized as valid */	/*	 * clear 

⌨️ 快捷键说明

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