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

📄 bt_verify.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 5 页
字号:
	for (p = pagelayout + himark;	    p < pagelayout + dbp->pgsize;	    p += RINTERNAL_SIZE)		if (*p != 1) {			EPRINT((dbp->dbenv,			    "Page %lu: gap between items at offset %lu",			    (u_long)pgno, (u_long)(p - pagelayout)));			isbad = 1;		}	if ((db_indx_t)himark != HOFFSET(h)) {		EPRINT((dbp->dbenv,		    "Page %lu: bad HOFFSET %lu, appears to be %lu",		    (u_long)pgno, (u_long)(HOFFSET(h)), (u_long)himark));		isbad = 1;	}	*nentriesp = nentries;err:	if ((t_ret =	    __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0 && ret == 0)		ret = t_ret;	if (pagelayout != NULL)		__os_free(dbp->dbenv, pagelayout);	return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);}/* * __bam_vrfy_inp -- *	Verify that all entries in inp[] array are reasonable; *	count them. */static int__bam_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags)	DB *dbp;	VRFY_DBINFO *vdp;	PAGE *h;	db_pgno_t pgno;	db_indx_t *nentriesp;	u_int32_t flags;{	BKEYDATA *bk;	BOVERFLOW *bo;	VRFY_CHILDINFO child;	VRFY_PAGEINFO *pip;	int isbad, initem, isdupitem, ret, t_ret;	u_int32_t himark, offset; /* These would be db_indx_ts but for algnmt.*/	u_int32_t i, endoff, nentries;	u_int8_t *pagelayout;	isbad = isdupitem = 0;	nentries = 0;	memset(&child, 0, sizeof(VRFY_CHILDINFO));	if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)		return (ret);	switch (TYPE(h)) {	case P_IBTREE:	case P_LBTREE:	case P_LDUP:	case P_LRECNO:		break;	default:		/*		 * In the salvager, we might call this from a page which		 * we merely suspect is a btree page.  Otherwise, it		 * shouldn't get called--if it is, that's a verifier bug.		 */		if (LF_ISSET(DB_SALVAGE))			break;		TYPE_ERR_PRINT(dbp->dbenv, "__bam_vrfy_inp", pgno, TYPE(h));		DB_ASSERT(0);		ret = EINVAL;		goto err;	}	/*	 * Loop through inp[], the array of items, until we either	 * run out of entries or collide with the data.  Keep track	 * of h_offset in himark.	 *	 * For each element in inp[i], make sure it references a region	 * that starts after the end of the inp array (as defined by	 * NUM_ENT(h)), ends before the beginning of the page, doesn't	 * overlap any other regions, and doesn't have a gap between	 * it and the region immediately after it.	 */	himark = dbp->pgsize;	if ((ret = __os_malloc(dbp->dbenv, dbp->pgsize, &pagelayout)) != 0)		goto err;	memset(pagelayout, 0, dbp->pgsize);	for (i = 0; i < NUM_ENT(h); i++) {		switch (ret = __db_vrfy_inpitem(dbp,		    h, pgno, i, 1, flags, &himark, &offset)) {		case 0:			break;		case DB_VERIFY_BAD:			isbad = 1;			continue;		case DB_VERIFY_FATAL:			isbad = 1;			goto err;		default:			DB_ASSERT(ret != 0);			break;		}		/*		 * We now have a plausible beginning for the item, and we know		 * its length is safe.		 *		 * Mark the beginning and end in pagelayout so we can make sure		 * items have no overlaps or gaps.		 */		bk = GET_BKEYDATA(dbp, h, i);#define	ITEM_BEGIN	1#define	ITEM_END	2		if (pagelayout[offset] == 0)			pagelayout[offset] = ITEM_BEGIN;		else if (pagelayout[offset] == ITEM_BEGIN) {			/*			 * Having two inp entries that point at the same patch			 * of page is legal if and only if the page is			 * a btree leaf and they're onpage duplicate keys--			 * that is, if (i % P_INDX) == 0.			 */			if ((i % P_INDX == 0) && (TYPE(h) == P_LBTREE)) {				/* Flag for later. */				F_SET(pip, VRFY_HAS_DUPS);				/* Bump up nentries so we don't undercount. */				nentries++;				/*				 * We'll check to make sure the end is				 * equal, too.				 */				isdupitem = 1;			} else {				isbad = 1;				EPRINT((dbp->dbenv,				    "Page %lu: duplicated item %lu",				    (u_long)pgno, (u_long)i));			}		}		/*		 * Mark the end.  Its location varies with the page type		 * and the item type.		 *		 * If the end already has a sign other than 0, do nothing--		 * it's an overlap that we'll catch later.		 */		switch(B_TYPE(bk->type)) {		case B_KEYDATA:			if (TYPE(h) == P_IBTREE)				/* It's a BINTERNAL. */				endoff = offset + BINTERNAL_SIZE(bk->len) - 1;			else				endoff = offset + BKEYDATA_SIZE(bk->len) - 1;			break;		case B_DUPLICATE:			/*			 * Flag that we have dups; we'll check whether			 * that's okay during the structure check.			 */			F_SET(pip, VRFY_HAS_DUPS);			/* FALLTHROUGH */		case B_OVERFLOW:			/*			 * Overflow entries on internal pages are stored			 * as the _data_ of a BINTERNAL;  overflow entries			 * on leaf pages are stored as the entire entry.			 */			endoff = offset +			    ((TYPE(h) == P_IBTREE) ?			    BINTERNAL_SIZE(BOVERFLOW_SIZE) :			    BOVERFLOW_SIZE) - 1;			break;		default:			/*			 * We'll complain later;  for now, just mark			 * a minimum.			 */			endoff = offset + BKEYDATA_SIZE(0) - 1;			break;		}		/*		 * If this is an onpage duplicate key we've seen before,		 * the end had better coincide too.		 */		if (isdupitem && pagelayout[endoff] != ITEM_END) {			EPRINT((dbp->dbenv,			    "Page %lu: duplicated item %lu",			    (u_long)pgno, (u_long)i));			isbad = 1;		} else if (pagelayout[endoff] == 0)			pagelayout[endoff] = ITEM_END;		isdupitem = 0;		/*		 * There should be no deleted items in a quiescent tree,		 * except in recno.		 */		if (B_DISSET(bk->type) && TYPE(h) != P_LRECNO) {			isbad = 1;			EPRINT((dbp->dbenv,			    "Page %lu: item %lu marked deleted",			    (u_long)pgno, (u_long)i));		}		/*		 * Check the type and such of bk--make sure it's reasonable		 * for the pagetype.		 */		switch (B_TYPE(bk->type)) {		case B_KEYDATA:			/*			 * This is a normal, non-overflow BKEYDATA or BINTERNAL.			 * The only thing to check is the len, and that's			 * already been done.			 */			break;		case B_DUPLICATE:			if (TYPE(h) == P_IBTREE) {				isbad = 1;				EPRINT((dbp->dbenv,    "Page %lu: duplicate page referenced by internal btree page at item %lu",				    (u_long)pgno, (u_long)i));				break;			} else if (TYPE(h) == P_LRECNO) {				isbad = 1;				EPRINT((dbp->dbenv,	"Page %lu: duplicate page referenced by recno page at item %lu",				    (u_long)pgno, (u_long)i));				break;			}			/* FALLTHROUGH */		case B_OVERFLOW:			bo = (TYPE(h) == P_IBTREE) ?			    (BOVERFLOW *)(((BINTERNAL *)bk)->data) :			    (BOVERFLOW *)bk;			if (B_TYPE(bk->type) == B_OVERFLOW)				/* Make sure tlen is reasonable. */				if (bo->tlen > dbp->pgsize * vdp->last_pgno) {					isbad = 1;					EPRINT((dbp->dbenv,				"Page %lu: impossible tlen %lu, item %lu",					    (u_long)pgno,					    (u_long)bo->tlen, (u_long)i));					/* Don't save as a child. */					break;				}			if (!IS_VALID_PGNO(bo->pgno) || bo->pgno == pgno ||			    bo->pgno == PGNO_INVALID) {				isbad = 1;				EPRINT((dbp->dbenv,			    "Page %lu: offpage item %lu has bad pgno %lu",				    (u_long)pgno, (u_long)i, (u_long)bo->pgno));				/* Don't save as a child. */				break;			}			child.pgno = bo->pgno;			child.type = (B_TYPE(bk->type) == B_OVERFLOW ?			    V_OVERFLOW : V_DUPLICATE);			child.tlen = bo->tlen;			if ((ret = __db_vrfy_childput(vdp, pgno, &child)) != 0)				goto err;			break;		default:			isbad = 1;			EPRINT((dbp->dbenv,			    "Page %lu: item %lu of invalid type %lu",			    (u_long)pgno, (u_long)i));			break;		}	}	/*	 * Now, loop through and make sure the items are contiguous and	 * non-overlapping.	 */	initem = 0;	for (i = himark; i < dbp->pgsize; i++)		if (initem == 0)			switch (pagelayout[i]) {			case 0:				/* May be just for alignment. */				if (i != ALIGN(i, sizeof(u_int32_t)))					continue;				isbad = 1;				EPRINT((dbp->dbenv,				    "Page %lu: gap between items at offset %lu",				    (u_long)pgno, (u_long)i));				/* Find the end of the gap */				for ( ; pagelayout[i + 1] == 0 &&				    (size_t)(i + 1) < dbp->pgsize; i++)					;				break;			case ITEM_BEGIN:				/* We've found an item. Check its alignment. */				if (i != ALIGN(i, sizeof(u_int32_t))) {					isbad = 1;					EPRINT((dbp->dbenv,					    "Page %lu: offset %lu unaligned",					    (u_long)pgno, (u_long)i));				}				initem = 1;				nentries++;				break;			case ITEM_END:				/*				 * We've hit the end of an item even though				 * we don't think we're in one;  must				 * be an overlap.				 */				isbad = 1;				EPRINT((dbp->dbenv,				    "Page %lu: overlapping items at offset %lu",				    (u_long)pgno, (u_long)i));				break;			default:				/* Should be impossible. */				DB_ASSERT(0);				ret = EINVAL;				goto err;			}		else			switch (pagelayout[i]) {			case 0:				/* In the middle of an item somewhere. Okay. */				break;			case ITEM_END:				/* End of an item; switch to out-of-item mode.*/				initem = 0;				break;			case ITEM_BEGIN:				/*				 * Hit a second item beginning without an				 * end.  Overlap.				 */				isbad = 1;				EPRINT((dbp->dbenv,				    "Page %lu: overlapping items at offset %lu",				    (u_long)pgno, (u_long)i));				break;			}	(void)__os_free(dbp->dbenv, pagelayout);	/* Verify HOFFSET. */	if ((db_indx_t)himark != HOFFSET(h)) {		EPRINT((dbp->dbenv,		    "Page %lu: bad HOFFSET %lu, appears to be %lu",		    (u_long)pgno, (u_long)HOFFSET(h), (u_long)himark));		isbad = 1;	}err:	if (nentriesp != NULL)		*nentriesp = nentries;	if ((t_ret =	    __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0 && ret == 0)		ret = t_ret;	return ((isbad == 1 && ret == 0) ? DB_VERIFY_BAD : ret);}/* * __bam_vrfy_itemorder -- *	Make sure the items on a page sort correctly. * *	Assumes that NUM_ENT(h) and inp[0]..inp[NUM_ENT(h) - 1] are *	reasonable;  be sure that __bam_vrfy_inp has been called first. * *	If ovflok is set, it also assumes that overflow page chains *	hanging off the current page have been sanity-checked, and so we *	can use __bam_cmp to verify their ordering.  If it is not set, *	and we run into an overflow page, carp and return DB_VERIFY_BAD; *	we shouldn't be called if any exist. * * PUBLIC: int __bam_vrfy_itemorder __P((DB *, VRFY_DBINFO *, PAGE *, * PUBLIC:     db_pgno_t, u_int32_t, int, int, u_int32_t)); */int__bam_vrfy_itemorder(dbp, vdp, h, pgno, nentries, ovflok, hasdups, flags)	DB *dbp;	VRFY_DBINFO *vdp;	PAGE *h;	db_pgno_t pgno;	u_int32_t nentries;	int ovflok, hasdups;	u_int32_t flags;{	DBT dbta, dbtb, dup_1, dup_2, *p1, *p2, *tmp;	BTREE *bt;	BINTERNAL *bi;	BKEYDATA *bk;	BOVERFLOW *bo;	VRFY_PAGEINFO *pip;	db_indx_t i;	int cmp, freedup_1, freedup_2, isbad, ret, t_ret;	int (*dupfunc) __P((DB *, const DBT *, const DBT *));	int (*func) __P((DB *, const DBT *, const DBT *));	void *buf1, *buf2, *tmpbuf;	/*	 * We need to work in the ORDERCHKONLY environment where we might	 * not have a pip, but we also may need to work in contexts where	 * NUM_ENT isn't safe.	 */	if (vdp != NULL) {		if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)			return (ret);		nentries = pip->entries;	} else		pip = NULL;	ret = isbad = 0;	bo = NULL;			/* Shut up compiler. */	memset(&dbta, 0, sizeof(DBT));	F_SET(&dbta, DB_DBT_REALLOC);	memset(&dbtb, 0, sizeof(DBT));	F_SET(&dbtb, DB_DBT_REALLOC);	buf1 = buf2 = NULL;	DB_ASSERT(!LF_ISSET(DB_NOORDERCHK));	dupfunc = (dbp->dup_compare == NULL) ? __bam_defcmp : dbp->dup_compare;	if (TYPE(h) == P_LDUP)		func = dupfunc;	else {		func = __bam_defcmp;		if (dbp->bt_internal != NULL) {			bt = (BTREE *)dbp->bt_internal;			if (bt->bt_compare != NULL)				func = bt->bt_compare;		}	}	/*	 * We alternate our use of dbta and dbtb so that we can walk	 * through the page key-by-key without copying a dbt twice.	 * p1 is always the dbt for index i - 1, and p2 for index i.	 */	p1 = &dbta;	p2 = &dbtb;	/*	 * Loop through the entries.  nentries ought to contain the	 * actual count, and so is a safe way to terminate the loop;  whether	 * we inc. by one or two depends on whether we're a leaf page--	 * on a leaf page, we care only about keys.  On internal pages	 * and LDUP pages, we want to check the order of all entries.	 *	 * Note that on IBTREE pages, we start with item 1, since item	 * 0 doesn't get looked at by __bam_cmp.	 */	for (i = (TYPE(h) == P_IBTREE) ? 1 : 0; i < nentries;	    i += (TYPE(h) == P_LBTREE) ? P_INDX : O_INDX) {		/*		 * Put key i-1, now in p2, into p1, by swapping DBTs and bufs.		 */		tmp = p1;		p1 = p2;		p2 = tmp;		tmpbuf = buf1;		buf1 = buf2;		buf2 = tmpbuf;

⌨️ 快捷键说明

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