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

📄 fsckwsp.c

📁 在Linux内核从2.4升级到2.6时需要升级的软件包
💻 C
📖 第 1 页 / 共 5 页
字号:
 * PARAMETERS: *      first_block   - input - ordinal number of the first block in the extent *                              to check *      last_block    - input - ordinal number of the last block in the extent *                              to check *      is_EA         - input - !0 => the extent contains an inode's EA *                               0 => the extent contains something else *	msg_info_ptr  - input - information needed to issue messages for this *                              extent.  If NULL, no messages will be issued *      ino_recptr    - input - pointer to the fsck inode record describing the *                              inode to which this extent is allocated * * RETURNS: *      success: FSCK_OK *      failure: something else */int extent_record_dupchk(int64_t first_block,			 int64_t last_block,			 int8_t range_adj,			 int8_t is_EA,			 int8_t is_ACL,			 struct fsck_ino_msg_info *msg_info_ptr,			 struct fsck_inode_record *ino_recptr){	int erd_rc = FSCK_OK;	int dups_detected = 0;	struct dupall_blkrec *this_blkrec;	if (range_adj) {		/* the xad described an invalid range */		fsck_send_msg(fsck_BADBLKNO,			      fsck_ref_msg(msg_info_ptr->msg_dxdtyp),			      fsck_ref_msg(msg_info_ptr->msg_inotyp),			      fsck_ref_msg(msg_info_ptr->msg_inopfx),			      msg_info_ptr->msg_inonum);	}	/*	 * Look for duplicate blocks already detected for this extent	 */	while (first_block <= last_block) {		this_blkrec = dupall_find_blkrec(first_block, last_block);		if (!this_blkrec)			break;		/*		 * If this record goes beyond the extent, we need to split it.		 */		if ((this_blkrec->first_blk < first_block) ||		    (this_blkrec->last_blk > last_block)) {			erd_rc = blkall_split_blkrec(this_blkrec, first_block,						     last_block);			if (erd_rc)				return erd_rc;			/*			 * Check if the split caused the current record to			 * precede the extent we are processing			 */			if (this_blkrec->first_blk < first_block)				continue;		}		/*		 * Take care of the blocks preceding this record (if any)		 */		if (first_block < this_blkrec->first_blk) {			erd_rc = blkall_increment_owners(first_block,						this_blkrec->first_blk - 1,						msg_info_ptr);			if (erd_rc < 0)				return erd_rc;			else if (erd_rc)				dups_detected = 1;		}		this_blkrec->owner_count++;		first_block = this_blkrec->last_blk + 1;	}	/*	 * Take care of any remaining blocks	 */	if (first_block <= last_block) {		erd_rc = blkall_increment_owners(first_block, last_block,						 msg_info_ptr);		if (erd_rc < 0)			return erd_rc;		else if (erd_rc)			dups_detected = 1;	}	if (dups_detected && msg_info_ptr) {		/* claims at least 1 multiply allocated block */		ino_recptr->involved_in_dups = 1;		fsck_send_msg(fsck_DUPBLKREFS,			      fsck_ref_msg(msg_info_ptr->msg_inopfx),			      msg_info_ptr->msg_inonum);		if (!(inode_is_metadata(ino_recptr))) {			agg_recptr->corrections_needed = 1;			if (is_EA)				ino_recptr->clr_ea_fld = 1;			else if (is_ACL)				ino_recptr->clr_acl_fld = 1;			else				ino_recptr->selected_to_rls = 1;		}	}	return (FSCK_OK);}/***************************************************************************** * NAME: extent_record * * FUNCTION:  Record that each of the blocks in the given extent is allocated *            to some inode. * * PARAMETERS: *      first_block   - input - ordinal number of the first block in the extent *                              to check *      last_block    - input - ordinal number of the last block in the extent *                              to check * * NOTES:  Originally, this was intended to be a streamlined version of *         extent_record_dupchk, called only when the extent was known to *         not be multilply allocated.  However, it really wasn't any more *         efficient, so its simpler to just call extent_record_dupchk here. * * RETURNS: *      success: FSCK_OK *      failure: something else */int extent_record(int64_t first_block, int64_t last_block){	return extent_record_dupchk(first_block, last_block, 0, 0, 0, 0, 0);}/***************************************************************************** * NAME: extent_unrecord * * FUNCTION:  Decrement, in the fsck workspace block record, the owner count *            for each block in the given extent. * * PARAMETERS: *      first_block   - input - ordinal number of the first block in the extent *                              to check *      last_block    - input - ordinal number of the last block in the extent *                              to check * * NOTES:  Under certain circumstances, it is necessary to back out the record *         of an inode's ownership the recording of some extent already verified *         valid. * *         This function could be accomplished using other routines which *         include extent validation code, but, for performance reasons, *         this streamlined routine exists to minimize processing time. * *         Examples of these circumstances include: *          o Storage allocated for an inode's EA is valid, but the B+Tree *            rooted in the inode is structurally corrupt.  Then the portions *            of the tree which were recorded before the corruption was detected *            were backed out using routines which include validation code, and *            finally this routine is called to 'unrecord' the storage allocated *            for the EA. * *          o The B+Tree rooted in an inode was verified structurally correct, *            but the di_nblocks in the inode was found to be inconsistent with *            the tree.  In this case we assume the tree to be corrupt and *            back it out of the fsck workspace block map immediately.  This *            routine would be used for that purpose since the tree has already *            been verified structurally correct. * *          o An inode has been found to be valid, but claims ownership of at *            least one block claimed by another inode. At least one of the *            inodes is actually damaged.  The user has given permission to *            delete this inode, and so we need to decrement the number of *            owners for each block allocated to this inode.  This routine *            would be used for that purpose since the tree has already been *            verified structurally correct. * * * RETURNS: *      success: FSCK_OK *      failure: something else */int extent_unrecord(int64_t first_block, int64_t last_block){	int eu_rc = FSCK_OK;	struct dupall_blkrec *this_blkrec;	while (first_block <= last_block) {		this_blkrec = dupall_find_blkrec(first_block, last_block);		if (!this_blkrec)			break;		/*		 * If this record goes beyond the extent, we need to split it.		 */		if ((this_blkrec->first_blk < first_block) ||		    (this_blkrec->last_blk > last_block)) {			eu_rc = blkall_split_blkrec(this_blkrec, first_block,						    last_block);			if (eu_rc)				return eu_rc;			/*			 * Check if the split caused the current record to			 * precede the extent we are processing			 */			if (this_blkrec->first_blk < first_block)				continue;		}		/*		 * Take care of the blocks preceding this record (if any)		 */		if (first_block < this_blkrec->first_blk) {			eu_rc = blkall_mark_free(first_block,						 this_blkrec->first_blk - 1);			if (eu_rc)				return eu_rc;		}		this_blkrec->owner_count--;		if (this_blkrec->owner_count == 1) {			/* No longer a duplicate */			if (!this_blkrec->first_ref_resolved)				agg_recptr->unresolved_1stref_count--;			agg_recptr->dup_block_count--;			dupall_extract_blkrec(this_blkrec);		}		first_block = this_blkrec->last_blk + 1;	}	/*	 * Take care of any remaining blocks	 */	if (first_block <= last_block)		eu_rc = blkall_mark_free(first_block, last_block);	return (eu_rc);}/**************************************************************************** * NAME: fsblk_count_avail * * FUNCTION:  Count the number of contiguous aggregate blocks which are *            available, according to the fsck workspace block map, starting *            with the given (available) aggregate block. * * PARAMETERS: *      wspbits     - input - pointer to a page in the fsck workspace block map *      wordidx     - input - the ordinal number, in the page pointed to by *                            wspbits, of the word containing the bit representing *                            some particular aggregate block. *                            at routine entry: the block represented is the available *                                              block with which counting should start *                            at routine exit: the block represented is the 1st block *                                             AFTER the last block counted *      bitidx      - input - the ordinal number, in the word identified by wordidx, *                            of the bit representing some particular aggregate block. *                            at routine entry: the block represented is the available *                                              block with which counting should start *                            at routine exit: the block represented is the 1st block *                                             AFTER the last block counted *      num_wanted  - input - number of blocks wanted.  (i.e., when to stop counting *                            even if the run of contiguous, available blocks has *                            not ended. *      num_avail   - input - number of contiguous, available blocks counted starting *                            with the block described by wspbits, wordidx, and *                            bitidx when the routine was entered. * * RETURNS: *      success: FSCK_OK *      failure: something else */int fsblk_count_avail(uint32_t * wspbits,		      int32_t * wordidx,		      int32_t * bitidx, int32_t num_wanted, int32_t * num_avail){	int fbca_rc = FSCK_OK;	int done_counting = 0;	uint32_t bitmask;	*num_avail = 0;	while (((*wordidx) < LPERDMAP) && (!done_counting)) {		bitmask = 0x80000000u;		bitmask = bitmask >> (*bitidx);		while (((*bitidx) < DBWORD) && (!done_counting)) {			if (wspbits[*wordidx] & bitmask) {				/* this one's not available */				done_counting = -1;			} else {				/* this one's available */				(*num_avail)++;				if ((*num_avail) == num_wanted) {					done_counting = -1;				} else {					bitmask = bitmask >> 1;				}				(*bitidx)++;			}		}		/* end while bitidx */		if (!done_counting) {			*bitidx = 0;			*wordidx += 1;		}	}	return (fbca_rc);}/**************************************************************************** * NAME: fsblk_next_avail * * FUNCTION:  Find the next available aggregate block, according to the *            fsck workspace block map, starting with the given block. * * PARAMETERS: *      wspbits     - input - pointer to a page in the fsck workspace block map *      startword   - input - the ordinal number, in the page pointed to by *                            wspbits, of the word containing the bit representing *                            the aggregate block at which to start searching *      startbit    - input - the ordinal number, in the word identified by wordidx, *                            of the bit representing the aggregate block at which *                            to start searching *      foundword   - input - the ordinal number, in the page pointed to by *                            wspbits, of the word containing the bit representing *                            the available aggregate block found, if any *      foundbit    - input - the ordinal number, in the word identified by wordidx, *                            of the bit representing the available aggregate block, *                            if any *      block_found - input - pointer to a variable in which the search results are *                            returned.  !0 => an available block was found in the *                                             given page at/after the specified start *                                        0 => no available block was found in the *                                             given page at/after the specified start * * RETURNS: *      success: FSCK_OK *      failure: something else */int fsblk_next_avail(uint32_t * wspbits,		     int32_t startword,		     int32_t startbit,		     int32_t * foundword, int32_t * foundbit, int *block_found){	int fbna_rc = FSCK_OK;	int32_t wordidx, bitidx, firstbit;	uint32_t bitmask;	uint32_t mask_all_on = 0xFFFFFFFFu;	*block_found = 0;	firstbit = startbit;	for (wordidx = startword; ((wordidx < LPERDMAP) && (!(*block_found)));	     wordidx++) {		if (wspbits[wordidx] != mask_all_on) {			/* a zero in this map word */			bitmask = 0x80000000u;			bitmask = bitmask >> firstbit;			for (bitidx = firstbit;			     ((bitidx < DBWORD) && (!(*block_found)));			     bitidx++) {				if (!(wspbits[wordidx] & bitmask)) {					/* it's available */					*foundword = wordidx;					*foundbit = bitidx;					*block_found = -1;				} else {					/* it's in use */					bitmask = bitmask >> 1;				}			}		}		firstbit = 0;	}	return (fbna_rc);}/**************************************************************************** * NAME: fsck_alloc_fsblks * * FUNCTION: Allocate storage in the aggregate. * * PARAMETERS: *      blocks_wanted  - input - the number of contiguous blocks of storage *                               wanted *      blocks         - input - pointer to a variable in which the ordinal *                               number of the first block allocated will be *                               returned  (or 0 if the storage cannot be *                               allocated) * * NOTES: o This routine is only called when fsck has write access to the *          aggregate. * *        o This routine can not be called before the end of Phase 1 (that is, *          not before all block allocations existing in the aggregate have *          been recorded in the fsck workspace block map). * *        o The optimum time to call this routine is after all inode repairs *          have been performed (a step performed in Phase 6) since aggregates *          blocks may be made available by releasing inodes and/or clearing *          extents allocated for EAs. * *        o This routine can not be called after the beginning of Phase 8 (that *          is, not after fsck begins to rebuild the aggregate block map from *          the information in the fsck workspace block map). * *        o Currently, this routine is only called *           - during inode reconnect processing (the last step in Phase 6) to *              create new internal nodes for the directory to which the inode(s) *              is(are) reconnected. *           - during replication of the Aggregate Inode Map (Phase 7) when *              building the tree for the fileset AIM inode. * * RETURNS: *      success: FSCK_OK *      failure: something else */int fsck_alloc_fsblks(int32_t blocks_wanted, int

⌨️ 快捷键说明

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