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

📄 db_rec.c

📁 这是国外的resip协议栈
💻 C
📖 第 1 页 / 共 2 页
字号:
		 * link its next pointer to the free list.		 */		P_INIT(pagep, file_dbp->pgsize,		    argp->pgno, PGNO_INVALID, argp->next, 0, P_INVALID);		pagep->lsn = argp->page_lsn;		modified = 1;	}do_truncate:	/*	 * If the page was newly created, give it back, if	 * possible.  Otherwise put it into limbo.	 */	if ((pagep == NULL || IS_ZERO_LSN(LSN(pagep))) &&	    IS_ZERO_LSN(argp->page_lsn) && DB_UNDO(op)) {#ifdef HAVE_FTRUNCATE		COMPQUIET(info, NULL);		/* Discard the page. */		if (pagep != NULL) {			if ((ret =			     __memp_fput(mpf, pagep, DB_MPOOL_DISCARD)) != 0)				goto out;			pagep = NULL;			/* Give the page back to the OS. */			if (meta->last_pgno <= argp->pgno &&			    (ret = __memp_ftruncate(mpf, argp->pgno, 0)) != 0)				goto out;		}#else		/* Put the page in limbo.*/		if ((ret = __db_add_limbo(dbenv,		    info, argp->fileid, argp->pgno, 1)) != 0)			goto out;		/* The last_pgno grows if this was a new page. */		if (argp->pgno > meta->last_pgno) {			meta->last_pgno = argp->pgno;			meta_modified = 1;		}#endif	}	if (pagep != NULL &&	     (ret = __memp_fput(mpf,	     pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)		goto out;	pagep = NULL;	if ((ret = __memp_fput(mpf,	    meta, meta_modified ? DB_MPOOL_DIRTY : 0)) != 0)		goto out;	meta = NULL;done:	*lsnp = argp->prev_lsn;	ret = 0;out:	if (pagep != NULL)		(void)__memp_fput(mpf, pagep, 0);	if (meta != NULL)		(void)__memp_fput(mpf, meta, 0);	if (ret == ENOENT && op == DB_TXN_BACKWARD_ALLOC)		ret = 0;	REC_CLOSE;}/* * __db_pg_free_recover_int -- */static int__db_pg_free_recover_int(dbenv, argp, file_dbp, lsnp, mpf, op, data)	DB_ENV *dbenv;	__db_pg_freedata_args *argp;	DB *file_dbp;	DB_LSN *lsnp;	DB_MPOOLFILE *mpf;	db_recops op;	int data;{	DBMETA *meta;	DB_LSN copy_lsn;	PAGE *pagep;	db_pgno_t pgno;	int cmp_n, cmp_p, meta_modified, modified, ret;	meta = NULL;	pagep = NULL;	meta_modified = modified = 0;	/*	 * Get the metapage first so we can see where we are.	 */	pgno = PGNO_BASE_MD;	if ((ret = __memp_fget(mpf, &pgno, 0, &meta)) != 0) {		/* The metadata page must always exist. */		ret = __db_pgerr(file_dbp, pgno, ret);		goto out;	}	cmp_n = log_compare(lsnp, &LSN(meta));	cmp_p = log_compare(&LSN(meta), &argp->meta_lsn);	CHECK_LSN(op, cmp_p, &LSN(meta), &argp->meta_lsn);	/*	 * Fix up the metadata page.  If we're redoing or undoing the operation	 * we get the page and update its LSN, last and free pointer.	 */	if (cmp_p == 0 && DB_REDO(op)) {#ifdef HAVE_FTRUNCATE		/*		 * If we are at the end of the file truncate, otherwise		 * put on the free list.		*/		if (argp->pgno == argp->last_pgno)			meta->last_pgno = argp->pgno - 1;		else			meta->free = argp->pgno;#else		/* Need to redo the deallocation. */		meta->free = argp->pgno;		/*		 * If this was a compensating transaction and		 * we are a replica, then we never executed the		 * original allocation which incremented meta->free.		 */		if (meta->last_pgno < meta->free)			meta->last_pgno = meta->free;#endif		LSN(meta) = *lsnp;		meta_modified = 1;	} else if (cmp_n == 0 && DB_UNDO(op)) {		/* Need to undo the deallocation. */		meta->free = argp->next;		LSN(meta) = argp->meta_lsn;		if (meta->last_pgno < argp->pgno)			meta->last_pgno = argp->pgno;		meta_modified = 1;	}	/*	 * Get the freed page.  If we support truncate then don't	 * create the page if we are going to free it.  If we're	 * redoing the operation we get the page and explicitly discard	 * its contents, then update its LSN.  If we're undoing the	 * operation, we get the page and restore its header.	 * If we don't support truncate, then we must create the page	 * and roll it back.	 */#ifdef HAVE_FTRUNCATE	if (DB_REDO(op) || meta->last_pgno < argp->pgno) {		if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {			if (ret == DB_PAGE_NOTFOUND)				goto done;			goto out;		}	} else#endif	if ((ret =	    __memp_fget(mpf, &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)		goto out;	(void)__ua_memcpy(&copy_lsn, &LSN(argp->header.data), sizeof(DB_LSN));	cmp_n = IS_ZERO_LSN(LSN(pagep)) ? 0 : log_compare(lsnp, &LSN(pagep));	cmp_p = log_compare(&LSN(pagep), &copy_lsn);#ifdef HAVE_FTRUNCATE	/*	 * This page got extended by a later allocation,	 * but its allocation was not in the scope of this	 * recovery pass.	 */	if (IS_ZERO_LSN(LSN(pagep)))		cmp_p = 0;#endif	CHECK_LSN(op, cmp_p, &LSN(pagep), &copy_lsn);	if (DB_REDO(op) &&	    (cmp_p == 0 ||	    (IS_ZERO_LSN(copy_lsn) &&	    log_compare(&LSN(pagep), &argp->meta_lsn) <= 0))) {		/* Need to redo the deallocation. */#ifdef HAVE_FTRUNCATE		if (meta->last_pgno <= argp->pgno) {			if ((ret =			    __memp_fput(mpf, pagep, DB_MPOOL_DISCARD)) != 0)				goto out;			pagep = NULL;			if ((ret = __memp_ftruncate(mpf, argp->pgno, 0)) != 0)				goto out;		} else if (argp->last_pgno == argp->pgno) {			/* The page was truncated at runtime, zero it out. */			P_INIT(pagep, 0, PGNO_INVALID,			    PGNO_INVALID, PGNO_INVALID, 0, P_INVALID);			ZERO_LSN(pagep->lsn);			modified = 1;		} else#endif		{			P_INIT(pagep, file_dbp->pgsize,			    argp->pgno, PGNO_INVALID, argp->next, 0, P_INVALID);			pagep->lsn = *lsnp;			modified = 1;		}	} else if (cmp_n == 0 && DB_UNDO(op)) {		/* Need to reallocate the page. */		memcpy(pagep, argp->header.data, argp->header.size);		if (data)			memcpy((u_int8_t*)pagep + pagep->hf_offset,			     argp->data.data, argp->data.size);		modified = 1;	}	if (pagep != NULL &&	    (ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)		goto out;	pagep = NULL;#ifdef HAVE_FTRUNCATEdone:#endif	if ((ret = __memp_fput(mpf,	     meta, meta_modified ? DB_MPOOL_DIRTY : 0)) != 0)		goto out;	meta = NULL;	ret = 0;out:	if (pagep != NULL)		(void)__memp_fput(mpf, pagep, 0);	if (meta != NULL)		(void)__memp_fput(mpf, meta, 0);	return (ret);}/* * __db_pg_free_recover -- *	Recovery function for pg_free. * * PUBLIC: int __db_pg_free_recover * PUBLIC:   __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); */int__db_pg_free_recover(dbenv, dbtp, lsnp, op, info)	DB_ENV *dbenv;	DBT *dbtp;	DB_LSN *lsnp;	db_recops op;	void *info;{	DB *file_dbp;	DBC *dbc;	DB_MPOOLFILE *mpf;	__db_pg_free_args *argp;	int ret;	COMPQUIET(info, NULL);	REC_PRINT(__db_pg_free_print);	REC_INTRO(__db_pg_free_read, 1);	ret = __db_pg_free_recover_int(dbenv,	     (__db_pg_freedata_args *)argp, file_dbp, lsnp, mpf, op, 0);done:	*lsnp = argp->prev_lsn;out:	REC_CLOSE;}/* * __db_pg_new_recover -- *	A new page from the file was put on the free list. * This record is only generated during a LIMBO_COMPENSATE. * * PUBLIC: int __db_pg_new_recover * PUBLIC:   __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); */int__db_pg_new_recover(dbenv, dbtp, lsnp, op, info)	DB_ENV *dbenv;	DBT *dbtp;	DB_LSN *lsnp;	db_recops op;	void *info;{#ifndef HAVE_FTRUNCATE	DB *file_dbp;	DBC *dbc;	DB_MPOOLFILE *mpf;	__db_pg_free_args *argp;	int ret;	REC_PRINT(__db_pg_free_print);	REC_INTRO(__db_pg_free_read, 1);	COMPQUIET(op, DB_TXN_ABORT);	if ((ret =	    __db_add_limbo(dbenv, info, argp->fileid, argp->pgno, 1)) == 0)		*lsnp = argp->prev_lsn;done:out:	REC_CLOSE;#else	COMPQUIET(dbenv, NULL);	COMPQUIET(dbtp, NULL);	COMPQUIET(lsnp, NULL);	COMPQUIET(op, DB_TXN_PRINT);	COMPQUIET(info, NULL);	return (0);#endif}/* * __db_pg_freedata_recover -- *	Recovery function for pg_freedata. * * PUBLIC: int __db_pg_freedata_recover * PUBLIC:   __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); */int__db_pg_freedata_recover(dbenv, dbtp, lsnp, op, info)	DB_ENV *dbenv;	DBT *dbtp;	DB_LSN *lsnp;	db_recops op;	void *info;{	DB *file_dbp;	DBC *dbc;	DB_MPOOLFILE *mpf;	__db_pg_freedata_args *argp;	int ret;	COMPQUIET(info, NULL);	REC_PRINT(__db_pg_freedata_print);	REC_INTRO(__db_pg_freedata_read, 1);	ret = __db_pg_free_recover_int(dbenv, argp, file_dbp, lsnp, mpf, op, 1);done:	*lsnp = argp->prev_lsn;out:	REC_CLOSE;}/* * __db_cksum_recover -- *	Recovery function for checksum failure log record. * * PUBLIC: int __db_cksum_recover __P((DB_ENV *, * PUBLIC:      DBT *, DB_LSN *, db_recops, void *)); */int__db_cksum_recover(dbenv, dbtp, lsnp, op, info)	DB_ENV *dbenv;	DBT *dbtp;	DB_LSN *lsnp;	db_recops op;	void *info;{	__db_cksum_args *argp;	int ret;	COMPQUIET(info, NULL);	COMPQUIET(lsnp, NULL);	COMPQUIET(op, DB_TXN_ABORT);	REC_PRINT(__db_cksum_print);	if ((ret = __db_cksum_read(dbenv, dbtp->data, &argp)) != 0)		return (ret);	/*	 * We had a checksum failure -- the only option is to run catastrophic	 * recovery.	 */	if (F_ISSET(dbenv, DB_ENV_FATAL))		ret = 0;	else {		__db_err(dbenv,		    "Checksum failure requires catastrophic recovery");		ret = __db_panic(dbenv, DB_RUNRECOVERY);	}	__os_free(dbenv, argp);	return (ret);}/* * __db_pg_prepare_recover -- *	Recovery function for pg_prepare. * * PUBLIC: int __db_pg_prepare_recover * PUBLIC:   __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); */int__db_pg_prepare_recover(dbenv, dbtp, lsnp, op, info)	DB_ENV *dbenv;	DBT *dbtp;	DB_LSN *lsnp;	db_recops op;	void *info;{#ifndef HAVE_FTRUNCATE	__db_pg_prepare_args *argp;	DB *file_dbp;	DBC *dbc;	DB_MPOOLFILE *mpf;	PAGE *pagep;	int ret, t_ret;	REC_PRINT(__db_pg_prepare_print);	REC_INTRO(__db_pg_prepare_read, 1);	mpf = file_dbp->mpf;	/*	 * If this made it into the limbo list at prepare time then	 * it was a new free page allocated by an aborted subtransaction.	 * Only that subtransaction could have toched the page.	 * All other pages in the free list at this point are	 * either of the same nature or were put there by this subtransactions	 * other subtransactions that followed this one.  If	 * they were put there by this subtransaction the log records	 * of the following allocations will reflect that.	 * Note that only one transaction could have had the	 * metapage locked at the point of the crash.	 * All this is to say that we can P_INIT this page without	 * loosing other pages on the free list because they	 * will be linked in by records earlier in the log for	 * this transaction which we will roll back.	 */	if (op == DB_TXN_ABORT) {		if ((ret = __memp_fget(		    mpf, &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0)			goto out;		P_INIT(pagep, file_dbp->pgsize,		    argp->pgno, PGNO_INVALID, PGNO_INVALID, 0, P_INVALID);		ZERO_LSN(pagep->lsn);		ret = __db_add_limbo(dbenv, info, argp->fileid, argp->pgno, 1);		if ((t_ret =		    __memp_fput(mpf, pagep, DB_MPOOL_DIRTY)) != 0 && ret == 0)			ret = t_ret;	}done:	if (ret == 0)		*lsnp = argp->prev_lsn;out:	REC_CLOSE;#else	COMPQUIET(dbenv, NULL);	COMPQUIET(dbtp, NULL);	COMPQUIET(lsnp, NULL);	COMPQUIET(op, DB_TXN_PRINT);	COMPQUIET(info, NULL);	return (0);#endif}/* * __db_pg_init_recover -- *	Recovery function to reinit pages for truncate. * * PUBLIC: int __db_pg_init_recover * PUBLIC:   __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); */int__db_pg_init_recover(dbenv, dbtp, lsnp, op, info)	DB_ENV *dbenv;	DBT *dbtp;	DB_LSN *lsnp;	db_recops op;	void *info;{	__db_pg_init_args *argp;	DB *file_dbp;	DBC *dbc;	DB_LSN copy_lsn;	DB_MPOOLFILE *mpf;	PAGE *pagep;	int cmp_n, cmp_p, modified, ret;	COMPQUIET(info, NULL);	REC_PRINT(__db_pg_init_print);	REC_INTRO(__db_pg_init_read, 1);	mpf = file_dbp->mpf;	REC_FGET(mpf, argp->pgno, &pagep, done);	modified = 0;	(void)__ua_memcpy(&copy_lsn, &LSN(argp->header.data), sizeof(DB_LSN));	cmp_n = log_compare(lsnp, &LSN(pagep));	cmp_p = log_compare(&LSN(pagep), &copy_lsn);	CHECK_LSN(op, cmp_p, &LSN(pagep), &copy_lsn);	if (cmp_p == 0 && DB_REDO(op)) {		P_INIT(pagep, file_dbp->pgsize, PGNO(pagep), PGNO_INVALID,		    PGNO_INVALID, TYPE(pagep) == P_HASH ? 0 : 1, TYPE(pagep));		pagep->lsn = *lsnp;		modified = 1;	} else if (cmp_n == 0 && DB_UNDO(op)) {		/* Put the data back on the page. */		memcpy(pagep, argp->header.data, argp->header.size);		if (argp->data.size > 0)			memcpy((u_int8_t*)pagep + pagep->hf_offset,			     argp->data.data, argp->data.size);		modified = 1;	}	if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0)		goto out;done:	*lsnp = argp->prev_lsn;out:	REC_CLOSE;}

⌨️ 快捷键说明

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