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

📄 fsckconn.c

📁 在Linux内核从2.4升级到2.6时需要升级的软件包
💻 C
📖 第 1 页 / 共 2 页
字号:
								/* parent isn't marked for release (yet) */								dup_parent_detected								    = 0;								if (this_ext->								    inonum ==								    this_inorec->								    parent_inonum)								{									dup_parent_detected									    =									    -1;								} else {									/* need to check for dups in rest of list */									that_ext									    =									    this_ext->									    next;									while ((!dup_parent_detected) && (that_ext != NULL)) {										if (that_ext->ext_type == parent_extension)											/* another parent extension */											if (this_ext->inonum == that_ext->inonum) {												dup_parent_detected												    =												    -1;											}										that_ext										    =										    that_ext->										    next;									}								}								if (dup_parent_detected) {									/*									 * mark the parent's inode record for release									 */									that_inorec->									    selected_to_rls									    = 1;									/*									 * notify the user that the directory is bad									 */									fsck_send_msg									    (fsck_BADKEYS,									     fsck_ref_msg(fsck_directory),									     fsck_ref_msg(msg_info_ptr->msg_inopfx),									     this_ext->inonum,									     37);								}							}						}						this_ext = this_ext->next;					}				}			}		}		if (cdi_rc == FSCK_OK) {			cdi_rc =			    get_inorecptr_next(aggregate_inode, &ino_idx,					       &this_inorec);		}	}	return (cdi_rc);}/***************************************************************************** * NAME: check_link_counts * * FUNCTION:  Count links from child directories to their parents. * *	      Verify that the link count stored in each in-use inode *	      matches the number of links fsck observed for the inode. * * RETURNS: *      success: FSCK_OK *      failure: something else */int check_link_counts(){	int clc_rc = FSCK_OK;	uint32_t ino_idx;	int num_parents;	int invalid_count_seen = 0;	int low_stored_count_seen = 0;	struct fsck_inode_ext_record *this_ext;	struct fsck_inode_record *this_inorec;	struct fsck_inode_record *parent_inorec;	int done_looking = 0;	int aggregate_inode = 0;	int alloc_ifnull = 0;	struct fsck_ino_msg_info ino_msg_info;	struct fsck_ino_msg_info *msg_info_ptr;	msg_info_ptr = &ino_msg_info;	/* all fileset owned */	msg_info_ptr->msg_inopfx = fsck_fset_inode;	/*	 * count links from child directories to their parents	 *	 * (These can't be counted when the parent-child relationship	 * is observed because that observation occurs while processing	 * the parent and until the child is processed we don't know	 * whether the child is a directory or not.)	 */	clc_rc = get_inorecptr_first(aggregate_inode, &ino_idx, &this_inorec);	while ((clc_rc == FSCK_OK) && (this_inorec != NULL)) {		if ((this_inorec->in_use) && (!this_inorec->selected_to_rls)		    && (!this_inorec->ignore_alloc_blks)		    && (this_inorec->inode_type == directory_inode)) {			/* inode is in use, not being released, and is type directory */			/* for the self entry */			this_inorec->link_count++;			if ((this_inorec->parent_inonum == ROOT_I)			    && (agg_recptr->rootdir_rebuilt)) {				/*				 * special case: if the parent is root and root was				 * rebuilt, then don't increment parent				 */				if (this_inorec->inonum == ROOT_I) {					/*					 * special case: if this IS the root, then it's					 * link from itself to itself DOES count					 */					this_inorec->link_count++;				}			} else if (this_inorec->parent_inonum != 0) {				/* not an orphan */				clc_rc =				    get_inorecptr(aggregate_inode, alloc_ifnull,						  this_inorec->parent_inonum,						  &parent_inorec);				if ((clc_rc != FSCK_OK)				    || (parent_inorec == NULL)) {					clc_rc = FSCK_INTERNAL_ERROR_13;					fsck_send_msg(fsck_INTERNALERROR, clc_rc, ino_idx,						      this_inorec->parent_inonum, 0);				} else {					/* handle the first (and usually the only) parent. */					parent_inorec->link_count++;				}				if ((clc_rc == FSCK_OK)				    && (this_inorec->ext_rec != NULL)) {					/* there might be more parents */					num_parents = parent_count(this_inorec);					if (num_parents > 1) {						/* directory with illegal links */						this_inorec->unxpctd_prnts = 1;						agg_recptr->corrections_needed =						    1;						/*						 * Create an extension record for the parent inode						 * number now stored in the child inode record.						 * When we traverse the aggregate on-disk we'll copy						 * the stored value into this field of the inode record						 * for use when displaying paths to the inode.						 */						clc_rc =						    get_inode_extension						    (&this_ext);						if (clc_rc == FSCK_OK) {							/* got extension record */							this_ext->ext_type =							    parent_extension;							this_ext->inonum =							    this_inorec->							    parent_inonum;							this_ext->next =							    this_inorec->							    ext_rec;							this_inorec->ext_rec =							    this_ext;							this_inorec->							    parent_inonum = 0;							/* already counted the first							 * one, back when it was in the							 * workspace inode record itself							 */							this_ext =							    this_ext->next;							while ((clc_rc ==								FSCK_OK)							       && (this_ext !=								   NULL)) {								/* exten records to check */								if (this_ext->								    ext_type ==								    parent_extension)								{									clc_rc =									    get_inorecptr									    (aggregate_inode,									     alloc_ifnull,									     this_ext->									     inonum,									     &parent_inorec);									if ((clc_rc != FSCK_OK)									    ||									    (parent_inorec									     ==									     NULL))									{										clc_rc										    =										    FSCK_INTERNAL_ERROR_14;										fsck_send_msg										    (fsck_INTERNALERROR,										     clc_rc,										     ino_idx,										     this_ext->inonum,										     0);									} else {										parent_inorec->										    link_count++;									}								}								this_ext =								    this_ext->								    next;							}						}					}				}			}		}		if (clc_rc == FSCK_OK) {			clc_rc =			    get_inorecptr_next(aggregate_inode, &ino_idx,					       &this_inorec);		}	}	/*	 * verify that stored link counts match observed link counts	 *	 * We have added each observed link and subtracted the stored	 * count.  If the stored count is correct the result is 0.	 */	if (clc_rc == FSCK_OK) {		clc_rc =		    get_inorecptr_first(aggregate_inode, &ino_idx,					&this_inorec);		while ((clc_rc == FSCK_OK) && (this_inorec != NULL)		       && (!done_looking)) {			if ((this_inorec->in_use)			    && (!this_inorec->selected_to_rls)			    && (!this_inorec->ignore_alloc_blks)) {				/* inode is in use and not being released */				if (this_inorec->link_count != 0) {					/* stored link count doesn't match fsck's observations */					if (this_inorec->parent_inonum == 0) {						/* inode is an orphan */						this_inorec->crrct_link_count =						    1;					} else {						/* not an orphan */						this_inorec->crrct_link_count =						    1;						if (this_inorec->link_count > 0) {							low_stored_count_seen =							    1;						}						invalid_count_seen = 1;						fsck_send_msg(fsck_BADINOLKCT,							      fsck_ref_msg(msg_info_ptr->msg_inopfx),							      ino_idx);					}				}			}			if (clc_rc == FSCK_OK) {				clc_rc =				    get_inorecptr_next(aggregate_inode,						       &ino_idx, &this_inorec);			}		}		if ((clc_rc == FSCK_OK) && (invalid_count_seen)) {			if (agg_recptr->processing_readwrite) {				agg_recptr->corrections_approved = 1;				fsck_send_msg(fsck_WILLFIXLINKCTS);			} else {				/* no write access */				if (low_stored_count_seen) {					agg_recptr->ag_dirty = 1;				}				/*				 * reset all link counts (in the fsck workspace) to				 * zero so that we won't accidentally correct them				 * while doing link count adjustments.				 *				 * (Link count adjustments are side effects of approved				 * repairs.  For example, if a directory inode is				 * released, the link count of its parent directory				 * is decremented.)				 */				clc_rc =				    get_inorecptr_first(aggregate_inode,							&ino_idx, &this_inorec);				while ((clc_rc == FSCK_OK)				       && (this_inorec != NULL)) {					if (this_inorec->in_use) {						this_inorec->crrct_link_count =						    0;						this_inorec->link_count = 0;					}					clc_rc =					    get_inorecptr_next(aggregate_inode,							       &ino_idx,							       &this_inorec);				}				fsck_send_msg(fsck_BADLINKCTS);			}		}	}	return (clc_rc);}/***************************************************************************** * NAME: reset_parents * * FUNCTION: Adjust the fsck notations about the inode's parent(s) if *           the parent(s) are corrupt or approved for release. * * PARAMETERS: *      ino_recptr  - input - pointer to an fsck record describing the inode *      ino_idx     - input - ordinal number of the inode * * RETURNS: *      success: FSCK_OK *      failure: something else */int reset_parents(struct fsck_inode_record *ino_recptr, uint32_t ino_idx){	int resps_rc = FSCK_OK;	struct fsck_inode_ext_record *this_ext;	struct fsck_inode_ext_record *rest_of_list;	int parent_count = 0;	uint32_t stored_parent_inonum = 0;	struct fsck_inode_record *parent_inorecptr;	int aggregate_inode = 0;	int alloc_ifnull = 0;	/*	 * if this is a directory with illegal hard links the inode	 * number in the fsck inode record is the one stored in the	 * inode on disk.	 */	if ((ino_recptr->inode_type == directory_inode)	    && (ino_recptr->unxpctd_prnts)) {		/* dir with multiple parents */		/*		 * Save the value stored in the inode record and then clear it.		 */		stored_parent_inonum = ino_recptr->parent_inonum;		ino_recptr->parent_inonum = 0;	} else {		/* not a dir with multiple parents */		/*		 * the 1st parent observed is in the inode record.		 * Any others are in extension records.		 */		resps_rc = get_inorecptr(aggregate_inode, alloc_ifnull,					 ino_recptr->parent_inonum,					 &parent_inorecptr);		if ((resps_rc == FSCK_OK) && (parent_inorecptr == NULL)) {			resps_rc = FSCK_INTERNAL_ERROR_15;			fsck_send_msg(fsck_INTERNALERROR, resps_rc, ino_idx,				      ino_recptr->parent_inonum,				      0);		} else if (resps_rc == FSCK_OK) {			if ((ino_recptr->parent_inonum == ROOT_I)			    && (agg_recptr->rootdir_rebuilt)) {				/*				 * special case: if the parent is root and root				 * was rebuilt, then this is an orphan				 */				ino_recptr->parent_inonum = 0;				ino_recptr->link_count--;			} else if ((!parent_inorecptr->selected_to_rls)				   && (!parent_inorecptr->ignore_alloc_blks)) {				/*				 * keeping this parent and haven't found the				 * tree to be corrupt				 */				parent_count++;			} else {				/* releasing this parent */				ino_recptr->parent_inonum = 0;				ino_recptr->link_count--;			}		}	}	/*	 * detach the extensions list from the inode record	 */	this_ext = ino_recptr->ext_rec;	ino_recptr->ext_rec = NULL;	while ((resps_rc == FSCK_OK) && (this_ext != NULL)) {		/* there may be more parents */		rest_of_list = this_ext->next;		if (this_ext->ext_type != parent_extension) {			/* not a parent */			this_ext->next = ino_recptr->ext_rec;			ino_recptr->ext_rec = this_ext;		} else {			/* parent extension */			resps_rc = get_inorecptr(aggregate_inode, alloc_ifnull,						 this_ext->inonum,						 &parent_inorecptr);			if ((resps_rc == FSCK_OK) && (parent_inorecptr == NULL)) {				resps_rc = FSCK_INTERNAL_ERROR_16;				fsck_send_msg(fsck_INTERNALERROR, resps_rc, ino_idx,					      this_ext->inonum, 0);			} else if (resps_rc == FSCK_OK) {				if ((ino_recptr->parent_inonum == ROOT_I)				    && (agg_recptr->rootdir_rebuilt)) {					/*					 * special case: if the parent is root and					 * root was rebuilt, then this is an orphan					 */					release_inode_extension(this_ext);					ino_recptr->link_count--;				} else if ((!parent_inorecptr->selected_to_rls)					   && (!parent_inorecptr->					       ignore_alloc_blks)) {					/* keeping this parent */					parent_count++;					if (ino_recptr->parent_inonum == 0) {						ino_recptr->parent_inonum =						    this_ext->inonum;						release_inode_extension						    (this_ext);					} else {						/* put it back on the list */						this_ext->next =						    ino_recptr->ext_rec;						ino_recptr->ext_rec = this_ext;					}				} else {					/* releasing this parent */					release_inode_extension(this_ext);					ino_recptr->link_count--;				}			}		}		this_ext = rest_of_list;	}	/*	 * at this point, if there is at least 1 observed parent which	 * is not being released, then a parent inode number is stored in	 * the inode record and any other parents are described in extension	 * records.	 *	 * if this is not a directory inode, we're done.	 *	 * if this is a directory inode, need to recheck for illegal hard	 * links and incorrect parent inode entry.	 */	if ((resps_rc == FSCK_OK)	    && (ino_recptr->inode_type == directory_inode)) {		/* a directory */		if (parent_count == 1) {			/* 1 parent now */			if (ino_recptr->unxpctd_prnts) {				/* entered with multiple links */				/* reset flag */				ino_recptr->unxpctd_prnts = 0;				if (ino_recptr->parent_inonum !=				    stored_parent_inonum) {					/*					 * Remaining parent doesn't match the one					 * the on-device inode says owns it.					 */					ino_recptr->crrct_prnt_inonum = 1;					agg_recptr->corrections_needed = 1;					agg_recptr->corrections_approved = 1;				}			}		} else if (parent_count == 0) {			/* no parents now */			ino_recptr->crrct_prnt_inonum = 0;			ino_recptr->unxpctd_prnts = 0;		} else {			/* multiple parents still */			ino_recptr->unxpctd_prnts = 1;			agg_recptr->corrections_needed = 1;			resps_rc = get_inode_extension(&this_ext);			if (resps_rc == FSCK_OK) {				this_ext->ext_type = parent_extension;				this_ext->inonum = ino_recptr->parent_inonum;				this_ext->next = ino_recptr->ext_rec;				ino_recptr->ext_rec = this_ext;				ino_recptr->parent_inonum =				    stored_parent_inonum;			}		}	}	return (resps_rc);}

⌨️ 快捷键说明

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