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

📄 fsckbmap.c

📁 jfs 源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* *   Copyright (c) International Business Machines Corp., 2000-2002 * *   This program is free software;  you can redistribute it and/or modify *   it under the terms of the GNU General Public License as published by *   the Free Software Foundation; either version 2 of the License, or  *   (at your option) any later version. *  *   This program is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY;  without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See *   the GNU General Public License for more details. * *   You should have received a copy of the GNU General Public License *   along with this program;  if not, write to the Free Software  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* defines and includes common among the fsck.jfs modules */#include "xfsckint.h" /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  *  * superblock buffer pointer  *  *      defined in xchkdsk.c  */extern struct superblock *sb_ptr; /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  *  * fsck aggregate info structure pointer  *  *      defined in xchkdsk.c  */extern struct fsck_agg_record *agg_recptr; /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  *  * fsck block map info structure pointer  *  *      defined in xchkdsk.c  */extern struct fsck_bmap_record *bmap_recptr; /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  *  * For message processing  *  *      defined in xchkdsk.c  */extern char *verbose_msg_ptr;extern char *Vol_Label; /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  *  * Device information.  *  *      defined in xchkdsk.c  */extern HFILE Dev_IOPort;extern uint32_t Dev_blksize;/* VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV * * The following are internal to this file * */struct fsck_stree_proc_parms {	dmtree_t *buf_tree;	int8_t *buf_stree;	int8_t *wsp_stree;	int32_t nleafs;	int32_t l2nleafs;	int32_t leafidx;	int8_t budmin;	int page_level;	uint32_t page_ordno;	int8_t *lfval_error;	int8_t *intval_error;};int ctlpage_rebuild(int8_t);int ctlpage_verify(int8_t);int dmap_pwmap_rebuild(uint32_t *);int dmap_pmap_verify(uint32_t *);int dmap_tree_rebuild(int8_t *);int dmap_tree_verify(int8_t *);int dmappg_rebuild(int8_t *);int dmappg_verify(int8_t *);int init_bmap_info(void);int Ln_tree_rebuild(int, int64_t, struct dmapctl **, int8_t *);int Ln_tree_verify(int, int64_t, struct dmapctl **, int8_t *);int stree_rebuild(struct fsck_stree_proc_parms *, int8_t *);int stree_verify(struct fsck_stree_proc_parms *, int8_t *);int verify_blkall_summary_msgs(void);/* VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV *//***************************************************************************** * NAME: ctlpage_rebuild * * FUNCTION: Rebuild the control page of the filesystem block map. * * PARAMETERS: *      max_buddy  - input - the data value in the root of the highest *                           Lx page in the map. * * RETURNS: *      success: FSCK_OK *      failure: something else */int ctlpage_rebuild(int8_t max_buddy){	int bcr_rc = FSCK_OK;	int32_t highest_active_AG = 0, num_active_AGs = 0, num_inactive_AGs;	int64_t avg_free, actAG_free, inactAG_free;	int32_t l2nl, n, agidx, index, aglevel, agheight, agwidth, agstart;	bcr_rc = mapctl_get(bmap_recptr->bmpctl_agg_fsblk_offset,			    (void **) &(bmap_recptr->bmpctl_bufptr));	if (bcr_rc == FSCK_OK) {		/* swap if on big endian machine */		ujfs_swap_dbmap((struct dbmap *) bmap_recptr->bmpctl_bufptr);		bmap_recptr->bmpctl_bufptr->dn_mapsize =		    bmap_recptr->total_blocks;		bmap_recptr->bmpctl_bufptr->dn_nfree = bmap_recptr->free_blocks;		bmap_recptr->bmpctl_bufptr->dn_l2nbperpage =		    agg_recptr->log2_blksperpg;		bmap_recptr->bmpctl_bufptr->dn_numag = agg_recptr->num_ag;		bmap_recptr->bmpctl_bufptr->dn_maxlevel =		    BMAPSZTOLEV(agg_recptr->sb_agg_fsblk_length);		/* check out the active AGs */		for (agidx = 0; (agidx < MAXAG); agidx++) {				if (bmap_recptr->AGActive[agidx]) {				highest_active_AG = agidx;				num_active_AGs++;			}		}	/* end check out the active AGs */		bmap_recptr->bmpctl_bufptr->dn_maxag = highest_active_AG;		num_inactive_AGs = agg_recptr->num_ag - num_active_AGs;		inactAG_free = num_inactive_AGs * sb_ptr->s_agsize;		actAG_free = bmap_recptr->free_blocks - inactAG_free;		avg_free = actAG_free / num_active_AGs;		if ((bmap_recptr->bmpctl_bufptr->dn_agpref > highest_active_AG) 		    || (bmap_recptr->bmpctl_bufptr->dn_agfree[bmap_recptr->		     bmpctl_bufptr->dn_agpref] < avg_free)) {				/* preferred AG is not valid */			if (avg_free == 0) {				bmap_recptr->bmpctl_bufptr->dn_agpref = 0;			} else {				bmap_recptr->bmpctl_bufptr->dn_agpref = -1;				for (agidx = 0; ((agidx < MAXAG) &&						 (bmap_recptr->bmpctl_bufptr->						  dn_agpref < 0)); agidx++) {					if (bmap_recptr->AGFree_tbl[agidx] >= 					    avg_free) {						bmap_recptr->bmpctl_bufptr->						    dn_agpref = agidx;					}				}			}		}		aglevel = BMAPSZTOLEV(sb_ptr->s_agsize);		l2nl =		    agg_recptr->log2_blksperag - (L2BPERDMAP +						  aglevel * L2LPERCTL);		agheight = l2nl >> 1;		agwidth = 1 << (l2nl - (agheight << 1));		for (index = 5 - agheight, agstart = 0, n = 1; index > 0;		     index--) {			agstart += n;			n <<= 2;		}		bmap_recptr->bmpctl_bufptr->dn_aglevel = aglevel;		bmap_recptr->bmpctl_bufptr->dn_agheigth = agheight;		bmap_recptr->bmpctl_bufptr->dn_agwidth = agwidth;		bmap_recptr->bmpctl_bufptr->dn_agstart = agstart;		bmap_recptr->bmpctl_bufptr->dn_agl2size =		    agg_recptr->log2_blksperag;		bmap_recptr->bmpctl_bufptr->dn_agsize = sb_ptr->s_agsize;		bmap_recptr->bmpctl_bufptr->dn_maxfreebud = max_buddy;		for (agidx = 0; (agidx < MAXAG); agidx++) {				/* rebuild the free list */			bmap_recptr->bmpctl_bufptr->dn_agfree[agidx] =			    bmap_recptr->AGFree_tbl[agidx];		}		/* swap if on big endian machine */		ujfs_swap_dbmap(bmap_recptr->bmpctl_bufptr);		/*		 * write the updated control page back onto the device		 */		bcr_rc = mapctl_put((void *) bmap_recptr->bmpctl_bufptr);	}	return (bcr_rc);}/***************************************************************************** * NAME: ctlpage_verify * * FUNCTION: Verify the control page of the filesystem block map. * * PARAMETERS: *      max_buddy  - input - the data value which should be in the root *                           of the highest Lx page in the map. * * RETURNS: *      success: FSCK_OK *      failure: something else */int ctlpage_verify(int8_t max_buddy){	int bcv_rc = FSCK_OK;	unsigned agidx;	int32_t max_level = 0;	int32_t highest_active_AG = 0;	int32_t l2nl, n, index, aglevel, agheight, agwidth, agstart;	bcv_rc = mapctl_get(bmap_recptr->bmpctl_agg_fsblk_offset,			    (void **) &(bmap_recptr->bmpctl_bufptr));	if (bcv_rc == FSCK_OK) {			/* got the control page in the buffer */		/* swap if on big endian machine */		ujfs_swap_dbmap((struct dbmap *) bmap_recptr->bmpctl_bufptr);		if (bmap_recptr->bmpctl_bufptr->dn_mapsize != bmap_recptr->total_blocks) {				/* bad number of blocks in the aggregate */			bmap_recptr->ctl_other_error = -1;			fsck_send_msg(fsck_BMAPCASB);		}		if (bmap_recptr->bmpctl_bufptr->dn_nfree != bmap_recptr->free_blocks) {				/* bad number of free blocks in the aggregate */			bmap_recptr->ctl_other_error = -1;			fsck_send_msg(fsck_BMAPCNF);		}		if (bmap_recptr->bmpctl_bufptr->dn_l2nbperpage != agg_recptr->log2_blksperpg) {				/* bad log2( blocks per page ) */			bmap_recptr->ctl_other_error = -1;			fsck_send_msg(fsck_BMAPCL2BPP);		}		if (bmap_recptr->bmpctl_bufptr->dn_numag != agg_recptr->num_ag) {				/* bad number of alloc groups */			bmap_recptr->ctl_other_error = -1;			fsck_send_msg(fsck_BMAPCNAG);		}		max_level = BMAPSZTOLEV(agg_recptr->sb_agg_fsblk_length);		if (bmap_recptr->bmpctl_bufptr->dn_maxlevel != max_level) {				/* bad maximum block map level */			bmap_recptr->ctl_other_error = -1;			fsck_send_msg(fsck_BMAPCMXLVL);		}		for (agidx = 0; (agidx < MAXAG); agidx++) {				/* check out the active AGs */			if (bmap_recptr->AGActive[agidx]) {				highest_active_AG = agidx;			}		}		/*		 * format does not include blocks allocated to the bad block inode		 * when it determines the dn_maxag.  Subsequent activity may or		 * may not have altered dn_maxag based on blocks allocated to the		 * bad block inode.  All we know for sure is that dn_maxag shouldn't		 * be larger than appropriate for the highest allocated block.		 */		if (bmap_recptr->bmpctl_bufptr->dn_maxag > highest_active_AG) {				/* bad highest active alloc group */			bmap_recptr->ctl_other_error = -1;			fsck_send_msg(fsck_BMAPCMAAG);		}		if (bmap_recptr->bmpctl_bufptr->dn_agpref > highest_active_AG) {				/* bad preferred alloc group */			bmap_recptr->ctl_other_error = -1;			fsck_send_msg(fsck_BMAPCPAG);		}		aglevel = BMAPSZTOLEV(sb_ptr->s_agsize);		l2nl =		    agg_recptr->log2_blksperag - (L2BPERDMAP +						  aglevel * L2LPERCTL);		agheight = l2nl >> 1;		agwidth = 1 << (l2nl - (agheight << 1));		for (index = 5 - agheight, agstart = 0, n = 1; index > 0;		     index--) {			agstart += n;			n <<= 2;		}		/* end for index */		if (bmap_recptr->bmpctl_bufptr->dn_aglevel != aglevel) {				/* bad level holding an AG */			bmap_recptr->ctl_other_error = -1;			fsck_send_msg(fsck_BMAPCDMCLAG);		}		if (bmap_recptr->bmpctl_bufptr->dn_agheigth != agheight) {				/* bad dmapctl height holding an AG */			bmap_recptr->ctl_other_error = -1;			fsck_send_msg(fsck_BMAPCDMCLH);		}		if (bmap_recptr->bmpctl_bufptr->dn_agwidth != agwidth) {				/* bad width at level holding an AG */			bmap_recptr->ctl_other_error = -1;			fsck_send_msg(fsck_BMAPCDMCLW);		}		if (bmap_recptr->bmpctl_bufptr->dn_agstart != agstart) {				/* bad start idx at level holding an AG */			bmap_recptr->ctl_other_error = -1;			fsck_send_msg(fsck_BMAPCDMCSTI);		}		if (bmap_recptr->bmpctl_bufptr->dn_agl2size != agg_recptr->log2_blksperag) {				/* bad log2(fsblks per AG) */			bmap_recptr->ctl_other_error = -1;			fsck_send_msg(fsck_BMAPCL2BPAG);		}		if (bmap_recptr->bmpctl_bufptr->dn_agsize != sb_ptr->s_agsize) {				/* bad fsblks per AG */			bmap_recptr->ctl_other_error = -1;			fsck_send_msg(fsck_BMAPCBPAG);		}		if (bmap_recptr->bmpctl_bufptr->dn_maxfreebud != max_buddy) {				/* bad max free buddy system */			bmap_recptr->ctl_other_error = -1;			fsck_send_msg(fsck_BMAPCBMXB);		}		for (agidx = 0; (agidx < MAXAG); agidx++) {			/* verify the free list */			if (bmap_recptr->bmpctl_bufptr->dn_agfree[agidx] != 			    bmap_recptr->AGFree_tbl[agidx]) {					/* bad free blocks in the AG */				bmap_recptr->ctl_fctl_error = -1;				fsck_send_msg(fsck_BMAPCAGNF, agidx);			}		}	}	return (bcv_rc);}/***************************************************************************** * NAME: dmap_pwmap_rebuild * * FUNCTION:  Rebuild the pmap in the current block map dmap page. * * PARAMETERS: *      pmap_freeblks  - input - pointer to a variable in which the number *                               of free blocks described by the dmap page *                               will be returned. * * RETURNS: *      success: FSCK_OK *      failure: something else */int dmap_pwmap_rebuild(uint32_t * pmap_freeblks){	int bdpr_rc = FSCK_OK;	uint32_t bitmask;	int64_t wsp_pagenum;	uint32_t wsp_byteoffset;	struct fsck_blk_map_page *wsp_page;	uint32_t *wsp_bits = NULL;	int32_t map_wordidx, word_bitidx;	int8_t max_buddy;	/*	 * locate the section of the workspace bit map which corresponds	 * to this dmap's pmap	 */	bdpr_rc = blkmap_find_bit(bmap_recptr->dmap_1stblk, &wsp_pagenum,				  &wsp_byteoffset, &bitmask);	if (bdpr_rc == FSCK_OK) {		bdpr_rc = blkmap_get_page(wsp_pagenum, &wsp_page);		if (bdpr_rc == FSCK_OK) {			wsp_bits =			    (uint32_t *) ((char *) wsp_page + wsp_byteoffset);		}	}	*pmap_freeblks = 0;	if (bdpr_rc == FSCK_OK) {		for (map_wordidx = 0; (map_wordidx < LPERDMAP); map_wordidx++) {			max_buddy =			    ujfs_maxbuddy((char *) &(wsp_bits[map_wordidx]));			bmap_recptr->dmap_wsp_sleafs[map_wordidx] = max_buddy;			bmap_recptr->dmap_bufptr->wmap[map_wordidx] =			    wsp_bits[map_wordidx];			/*    			 * copy the word from workspace to buffer, 			 * into both the working map and the permanent map.			 */			bmap_recptr->dmap_bufptr->pmap[map_wordidx] = 			    wsp_bits[map_wordidx];			/*			 * count the free blocks described by the word			 */			bitmask = 0x80000000u;			for (word_bitidx = 0; (word_bitidx < DBWORD);			     word_bitidx++) {				if (!(wsp_bits[map_wordidx] & bitmask)) {					/* it's free */					(*pmap_freeblks)++;					agg_recptr->free_blocks_in_aggregate++;				} else {						/* it's allocated */					agg_recptr->blocks_used_in_aggregate++;				}	/* end else it's allocated */

⌨️ 快捷键说明

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