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

📄 fsckino.c

📁 jfs 源码
💻 C
📖 第 1 页 / 共 5 页
字号:
 *      failure: something else */int unrecord_valid_inode(struct dinode *inoptr, uint32_t inoidx,			 struct fsck_inode_record *inorecptr,			 struct fsck_ino_msg_info *msg_info_ptr){	int uvi_rc = FSCK_OK;	int64_t ea_blocks = 0;	int64_t acl_blocks = 0;	/*	 * unrecord the extent (if any) containing the EA	 */	if ((inoptr->di_ea.flag == DXD_EXTENT) && (!inorecptr->ignore_ea_blks)) {		ea_blocks = lengthDXD(&(inoptr->di_ea));		agg_recptr->blocks_for_eas -= ea_blocks;		uvi_rc = backout_EA(inoptr, inorecptr);	}	/*	 * unrecord the extent (if any) containing the ACL	 */	if ((inoptr->di_acl.flag == DXD_EXTENT)	    && (!inorecptr->ignore_acl_blks)) {		acl_blocks = lengthDXD(&(inoptr->di_acl));		agg_recptr->blocks_for_acls -= acl_blocks;		uvi_rc = backout_ACL(inoptr, inorecptr);	}	/*	 * unrecord the extents (if any) describing data	 *	 * note that the tree is valid or we'd be ignoring these allocated	 * blocks.	 */	if (uvi_rc == FSCK_OK) {		if (inorecptr->inode_type == directory_inode) {			agg_recptr->blocks_for_dirs -=			    inoptr->di_nblocks - ea_blocks;			uvi_rc =			    process_valid_dir_data(inoptr, inoidx, inorecptr,						   msg_info_ptr, FSCK_UNRECORD);		} else {			agg_recptr->blocks_for_files -=			    inoptr->di_nblocks - ea_blocks;			uvi_rc =			    process_valid_data(inoptr, inoidx, inorecptr,					       msg_info_ptr, FSCK_UNRECORD);		}	}	return (uvi_rc);}/***************************************************************************** * NAME: validate_ACL * * FUNCTION: Determine whether the structures in the specified inode to *           describe ACL 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_ACL(struct dinode *inoptr, uint32_t inoidx,		 struct fsck_inode_record *inorecptr,		 struct fsck_ino_msg_info *msg_info_ptr){	int vacl_rc = FSCK_OK;	dxd_t *dxd_ptr;	uint32_t recorded_length, shortest_valid, longest_valid;	uint32_t ext_length;	int64_t ext_address;	int8_t extent_is_valid = 0;	uint16_t size16;	struct dinode an_inode;	dxd_ptr = &(inoptr->di_acl);	msg_info_ptr->msg_dxdtyp = fsck_ACL;	if (dxd_ptr->flag == 0)		goto out;	/* there is an ACL for this inode */	if ((dxd_ptr->flag != DXD_EXTENT) && (dxd_ptr->flag != DXD_INLINE)	    && (dxd_ptr->flag != DXD_CORRUPT)) {		/* not a single extent AND not inline AND not already		 * reported */		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_acl_fld = 1;		inorecptr->ignore_acl_blks = 1;		agg_recptr->corrections_needed = 1;		goto out;	}	/* else the acl flag is ok */	if (dxd_ptr->flag == DXD_INLINE) {		/* ACL is inline  */		size16 = sizeof (an_inode.di_inlineea);		agg_recptr->this_inode.acl_inline = 1;		agg_recptr->this_inode.inline_acl_length =		    (uint16_t) dxd_ptr->size;		agg_recptr->this_inode.inline_acl_offset =		    (uint16_t) addressDXD(dxd_ptr);		if ((dxd_ptr->size == 0)		    || (dxd_ptr->size >			(size16 - agg_recptr->this_inode.inline_acl_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_acl_fld = 1;			agg_recptr->corrections_needed = 1;		}	} else if (dxd_ptr->flag == DXD_EXTENT) {		/* else the ACL 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));			inorecptr->clr_acl_fld = 1;			inorecptr->ignore_acl_blks = 1;			agg_recptr->corrections_needed = 1;			recorded_length = 0;			extent_is_valid = 0;		} else {			/* length and size might be ok */			agg_recptr->this_inode.acl_blks = ext_length;			ext_address = addressDXD(dxd_ptr);			vacl_rc =			    process_extent(inorecptr, ext_length, ext_address,					   0, -1, msg_info_ptr,					   &recorded_length, &extent_is_valid,					   FSCK_RECORD_DUPCHECK);			/*			 * add the blocks in the ACL extent to the running 			 * totals for the fileset 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_acl_fld = 1;			agg_recptr->corrections_needed = 1;		}	}      out:	return (vacl_rc);}/***************************************************************************** * NAME: validate_dasd_used * * FUNCTION: Verify that, for each directory with a dasd limit set, the *	     cumulative amount of dasd used matches the value stored in the *	     inode. * * PARAMETERS:  none * * RETURNS: *      success: FSCK_OK *      failure: something else */int validate_dasd_used(){	int vdu_rc = FSCK_OK;	uint32_t ino_idx;	struct dinode *inoptr;	struct fsck_inode_record *this_inorec;	int aggregate_inode = 0;	/* going for fileset inodes only */	int which_it = 0;	/* in release 1 there is only fileset 0 */	int64_t dasd_used = 0;	/*	 * We make a single pass on the inode records:	 *	 *     if the inode record shows that the inode has a dasd limit,	 *     verify that the dasd used amount stored in the inode matches	 *     the amount calculated for the inode by fsck.	 */	vdu_rc = get_inorecptr_first(aggregate_inode, &ino_idx, &this_inorec);	while ((vdu_rc == FSCK_OK) && (this_inorec != NULL)	       && (ino_idx < ROOT_I)) {		/* not interesting until we get to the root inode */		vdu_rc =		    get_inorecptr_next(aggregate_inode, &ino_idx, &this_inorec);	}			/* end while */	while ((vdu_rc == FSCK_OK) && (this_inorec != NULL)) {		if ((this_inorec->in_use) && (!this_inorec->selected_to_rls)) {			/* inode in use and not selected to release */			if (this_inorec->inode_type == directory_inode) {				/* it's a directory */				vdu_rc =				    inode_get(aggregate_inode, which_it,					      ino_idx, &inoptr);				if (vdu_rc != FSCK_OK)					goto out;				/* got the inode */				dasd_used = DASDUSED(&(inoptr->di_DASD));				if (dasd_used != this_inorec->cumm_blocks) {					/* it isn't right! */					this_inorec->crrct_cumm_blks = 1;					agg_recptr->corrections_needed = 1;					agg_recptr->corrections_approved = 1;				}			}		}		vdu_rc =		    get_inorecptr_next(aggregate_inode, &ino_idx, &this_inorec);	}      out:	return (vdu_rc);}/***************************************************************************** * NAME: validate_data * * FUNCTION: Determine whether the structures in, or rooted in, the specified *           non-directory inode to describe 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_data(struct dinode *inoptr, uint32_t inoidx,		  struct fsck_inode_record *inorecptr,		  struct fsck_ino_msg_info *msg_info_ptr){	int vd_rc = FSCK_OK;	int intermed_rc = FSCK_OK;	dxd_t *dxd_ptr;	xtpage_t *xtp_ptr;	dxd_ptr = &(inoptr->di_dxd);	/* the data root dxd */	msg_info_ptr->msg_dxdtyp = fsck_objcontents;	/*	 * Symbolic link is a special case.  If the value fits within the	 * inode, the dxd appears to be an empty xtree, but it's unused.	 * In this case, ignore the dxd.	 */	if (ISLNK(inoptr->di_mode) && (inoptr->di_size < IDATASIZE)) {		/* Null terminator stored but not accounted for in di_size */		agg_recptr->this_inode.in_inode_data_length =			inoptr->di_size + 1;		goto out;	}	/*	 * examine the data field	 */	if (dxd_ptr->flag == 0)		goto out;	if ((dxd_ptr->flag == (DXD_INDEX | BT_ROOT | BT_LEAF))	    || (dxd_ptr->flag == (DXD_INDEX | BT_ROOT | BT_INTERNAL))) {		/*		 * to be valid, it has to be a B-tree node,		 * either root-leaf or root-internal		 */		/*		 * figure out how much space the root occupies in the inode		 * itself		 */		xtp_ptr = (xtpage_t *) (&inoptr->di_btroot);		agg_recptr->this_inode.in_inode_data_length =		    (xtp_ptr->header.maxentry - 2) * sizeof (xad_t);		/*		 * the dxd actually starts 32 bytes (== 2 * length of		 * an xad) before the boundary.		 * the 0th and 1st entries in the xad array are		 * really the header		 */		/*		 * validate the tree contents and record the extents it		 * describes until and unless the tree is found to be corrupt		 */		vd_rc =		    xTree_processing(inoptr, inoidx, inorecptr, msg_info_ptr,				     FSCK_RECORD_DUPCHECK);		if (vd_rc <= FSCK_OK)			goto out;		/* nothing fatal */		if (inorecptr->selected_to_rls &&		    inode_is_metadata(inorecptr)) {			vd_rc = FSCK_BADMDDATAIDX;		} else if (inorecptr->ignore_alloc_blks) {			/* the tree info can't be used */			if (inode_is_metadata(inorecptr)) {				vd_rc = FSCK_BADMDDATAIDX;			}			/*			 * 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) {				vd_rc = intermed_rc;				goto out;			}			if (intermed_rc != FSCK_OK) {				if (vd_rc == FSCK_OK) {					vd_rc = intermed_rc;				}			}			if (!inorecptr->ignore_ea_blks) {				intermed_rc = backout_EA(inoptr, inorecptr);				if (intermed_rc < 0) {					vd_rc = intermed_rc;					goto out;				}				if (intermed_rc != FSCK_OK) {					if (vd_rc == FSCK_OK) {						vd_rc = intermed_rc;					}				}				if (!inorecptr->ignore_acl_blks) {					intermed_rc =					    backout_ACL(inoptr, inorecptr);					if (intermed_rc < 0) {						vd_rc = intermed_rc;						goto out;					}					if (intermed_rc != FSCK_OK) {						if (vd_rc == FSCK_OK) {							vd_rc = intermed_rc;						}					}				}			}		}	} else {		/* else not B+ Tree index */		/*		 * the data root is not valid...the info cannot be trusted		 */		if (inode_is_metadata(inorecptr)) {			vd_rc = FSCK_BADMDDATA;		} else {			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));	}      out:	return (vd_rc);}/***************************************************************************** * NAME: validate_dir_data * * FUNCTION: Determine whether the structures in, or rooted in, the *           specified directory inode to describe 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_dir_data(struct dinode *inoptr, uint32_t inoidx,		      struct fsck_inode_record *inorecptr,		      struct fsck_ino_msg_info *msg_info_ptr){	int vdd_rc = FSCK_OK;	int intermed_rc = FSCK_OK;	int dtree_rc = FSCK_OK;	dxd_t *dxd_ptr;	int8_t save_ignore_alloc_blks;	int8_t xt_ignore_alloc_blks = 0;	dxd_ptr = &(inoptr->di_dxd);	/* the data root dxd */

⌨️ 快捷键说明

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