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

📄 mp_bh.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 2 页
字号:
/*- * See the file LICENSE for redistribution information. * * Copyright (c) 1996-2002 *	Sleepycat Software.  All rights reserved. */#include "db_config.h"#ifndef lintstatic const char revid[] = "$Id: mp_bh.c,v 11.71 2002/09/04 19:06:45 margo Exp $";#endif /* not lint */#ifndef NO_SYSTEM_INCLUDES#include <sys/types.h>#include <string.h>#include <unistd.h>#endif#include "db_int.h"#include "dbinc/db_shash.h"#include "dbinc/mp.h"#include "dbinc/log.h"#include "dbinc/db_page.h"static int __memp_pgwrite	   __P((DB_MPOOL *, DB_MPOOLFILE *, DB_MPOOL_HASH *, BH *));static int __memp_upgrade __P((DB_MPOOL *, DB_MPOOLFILE *, MPOOLFILE *));/* * __memp_bhwrite -- *	Write the page associated with a given buffer header. * * PUBLIC: int __memp_bhwrite __P((DB_MPOOL *, * PUBLIC:      DB_MPOOL_HASH *, MPOOLFILE *, BH *, int)); */int__memp_bhwrite(dbmp, hp, mfp, bhp, open_extents)	DB_MPOOL *dbmp;	DB_MPOOL_HASH *hp;	MPOOLFILE *mfp;	BH *bhp;	int open_extents;{	DB_ENV *dbenv;	DB_MPOOLFILE *dbmfp;	DB_MPREG *mpreg;	int local_open, incremented, ret;	dbenv = dbmp->dbenv;	local_open = incremented = 0;	/*	 * If the file has been removed or is a closed temporary file, jump	 * right ahead and pretend that we've found the file we want -- the	 * page-write function knows how to handle the fact that we don't have	 * (or need!) any real file descriptor information.	 */	if (F_ISSET(mfp, MP_DEADFILE)) {		dbmfp = NULL;		goto found;	}	/*	 * Walk the process' DB_MPOOLFILE list and find a file descriptor for	 * the file.  We also check that the descriptor is open for writing.	 * If we find a descriptor on the file that's not open for writing, we	 * try and upgrade it to make it writeable.  If that fails, we're done.	 */	MUTEX_THREAD_LOCK(dbenv, dbmp->mutexp);	for (dbmfp = TAILQ_FIRST(&dbmp->dbmfq);	    dbmfp != NULL; dbmfp = TAILQ_NEXT(dbmfp, q))		if (dbmfp->mfp == mfp) {			if (F_ISSET(dbmfp, MP_READONLY) &&			    !F_ISSET(dbmfp, MP_UPGRADE) &&			    (F_ISSET(dbmfp, MP_UPGRADE_FAIL) ||			    __memp_upgrade(dbmp, dbmfp, mfp))) {				MUTEX_THREAD_UNLOCK(dbenv, dbmp->mutexp);				return (EPERM);			}			/*			 * Increment the reference count -- see the comment in			 * __memp_fclose_int().			 */			++dbmfp->ref;			incremented = 1;			break;		}	MUTEX_THREAD_UNLOCK(dbenv, dbmp->mutexp);	if (dbmfp != NULL)		goto found;	/*	 * !!!	 * It's the caller's choice if we're going to open extent files.	 */	if (!open_extents && F_ISSET(mfp, MP_EXTENT))		return (EPERM);	/*	 * !!!	 * Don't try to attach to temporary files.  There are two problems in	 * trying to do that.  First, if we have different privileges than the	 * process that "owns" the temporary file, we might create the backing	 * disk file such that the owning process couldn't read/write its own	 * buffers, e.g., memp_trickle running as root creating a file owned	 * as root, mode 600.  Second, if the temporary file has already been	 * created, we don't have any way of finding out what its real name is,	 * and, even if we did, it was already unlinked (so that it won't be	 * left if the process dies horribly).  This decision causes a problem,	 * however: if the temporary file consumes the entire buffer cache,	 * and the owner doesn't flush the buffers to disk, we could end up	 * with resource starvation, and the memp_trickle thread couldn't do	 * anything about it.  That's a pretty unlikely scenario, though.	 *	 * Note we should never get here when the temporary file in question	 * has already been closed in another process, in which case it should	 * be marked MP_DEADFILE.	 */	if (F_ISSET(mfp, MP_TEMP))		return (EPERM);	/*	 * It's not a page from a file we've opened.  If the file requires	 * input/output processing, see if this process has ever registered	 * information as to how to write this type of file.  If not, there's	 * nothing we can do.	 */	if (mfp->ftype != 0) {		MUTEX_THREAD_LOCK(dbenv, dbmp->mutexp);		for (mpreg = LIST_FIRST(&dbmp->dbregq);		    mpreg != NULL; mpreg = LIST_NEXT(mpreg, q))			if (mpreg->ftype == mfp->ftype)				break;		MUTEX_THREAD_UNLOCK(dbenv, dbmp->mutexp);		if (mpreg == NULL)			return (EPERM);	}	/*	 * Try and open the file, attaching to the underlying shared area.	 * Ignore any error, assume it's a permissions problem.	 *	 * XXX	 * There's no negative cache, so we may repeatedly try and open files	 * that we have previously tried (and failed) to open.	 */	if ((ret = dbenv->memp_fcreate(dbenv, &dbmfp, 0)) != 0)		return (ret);	if ((ret = __memp_fopen_int(dbmfp, mfp,	    R_ADDR(dbmp->reginfo, mfp->path_off),	    0, 0, mfp->stat.st_pagesize)) != 0) {		(void)dbmfp->close(dbmfp, 0);		return (ret);	}	local_open = 1;found:	ret = __memp_pgwrite(dbmp, dbmfp, hp, bhp);	MUTEX_THREAD_LOCK(dbenv, dbmp->mutexp);	if (incremented)		--dbmfp->ref;	else if (local_open)		F_SET(dbmfp, MP_FLUSH);	MUTEX_THREAD_UNLOCK(dbenv, dbmp->mutexp);	return (ret);}/* * __memp_pgread -- *	Read a page from a file. * * PUBLIC: int __memp_pgread __P((DB_MPOOLFILE *, DB_MUTEX *, BH *, int)); */int__memp_pgread(dbmfp, mutexp, bhp, can_create)	DB_MPOOLFILE *dbmfp;	DB_MUTEX *mutexp;	BH *bhp;	int can_create;{	DB_IO db_io;	DB_ENV *dbenv;	DB_MPOOL *dbmp;	MPOOLFILE *mfp;	size_t len, nr, pagesize;	int ret;	dbmp = dbmfp->dbmp;	dbenv = dbmp->dbenv;	mfp = dbmfp->mfp;	pagesize = mfp->stat.st_pagesize;	/* We should never be called with a dirty or a locked buffer. */	DB_ASSERT(!F_ISSET(bhp, BH_DIRTY | BH_DIRTY_CREATE | BH_LOCKED));	/* Lock the buffer and swap the hash bucket lock for the buffer lock. */	F_SET(bhp, BH_LOCKED | BH_TRASH);	MUTEX_LOCK(dbenv, &bhp->mutex);	MUTEX_UNLOCK(dbenv, mutexp);	/*	 * Temporary files may not yet have been created.  We don't create	 * them now, we create them when the pages have to be flushed.	 */	nr = 0;	if (F_ISSET(dbmfp->fhp, DB_FH_VALID)) {		db_io.fhp = dbmfp->fhp;		db_io.mutexp = dbmfp->mutexp;		db_io.pagesize = db_io.bytes = pagesize;		db_io.pgno = bhp->pgno;		db_io.buf = bhp->buf;		/*		 * The page may not exist; if it doesn't, nr may well be 0,		 * but we expect the underlying OS calls not to return an		 * error code in this case.		 */		if ((ret = __os_io(dbenv, &db_io, DB_IO_READ, &nr)) != 0)			goto err;	}	if (nr < pagesize) {		/*		 * Don't output error messages for short reads.  In particular,		 * DB recovery processing may request pages never written to		 * disk or for which only some part have been written to disk,		 * in which case we won't find the page.  The caller must know		 * how to handle the error.		 */		if (can_create == 0) {			ret = DB_PAGE_NOTFOUND;			goto err;		}		/* Clear any bytes that need to be cleared. */		len = mfp->clear_len == 0 ? pagesize : mfp->clear_len;		memset(bhp->buf, 0, len);#if defined(DIAGNOSTIC) || defined(UMRW)		/*		 * If we're running in diagnostic mode, corrupt any bytes on		 * the page that are unknown quantities for the caller.		 */		if (len < pagesize)			memset(bhp->buf + len, CLEAR_BYTE, pagesize - len);#endif		++mfp->stat.st_page_create;	} else		++mfp->stat.st_page_in;	/* Call any pgin function. */	ret = mfp->ftype == 0 ? 0 : __memp_pg(dbmfp, bhp, 1);	/* Unlock the buffer and reacquire the hash bucket lock. */err:	MUTEX_UNLOCK(dbenv, &bhp->mutex);	MUTEX_LOCK(dbenv, mutexp);	/*	 * If no errors occurred, the data is now valid, clear the BH_TRASH	 * flag; regardless, clear the lock bit and let other threads proceed.	 */	F_CLR(bhp, BH_LOCKED);	if (ret == 0)		F_CLR(bhp, BH_TRASH);	return (ret);}/* * __memp_pgwrite -- *	Write a page to a file. */static int__memp_pgwrite(dbmp, dbmfp, hp, bhp)	DB_MPOOL *dbmp;	DB_MPOOLFILE *dbmfp;	DB_MPOOL_HASH *hp;	BH *bhp;{	DB_ENV *dbenv;	DB_IO db_io;	DB_LSN lsn;	MPOOLFILE *mfp;	size_t nw;	int callpgin, ret;	dbenv = dbmp->dbenv;	mfp = dbmfp == NULL ? NULL : dbmfp->mfp;	callpgin = ret = 0;	/*	 * We should never be called with a clean or trash buffer.	 * The sync code does call us with already locked buffers.	 */	DB_ASSERT(F_ISSET(bhp, BH_DIRTY));	DB_ASSERT(!F_ISSET(bhp, BH_TRASH));	/*	 * If we have not already traded the hash bucket lock for the buffer	 * lock, do so now.	 */	if (!F_ISSET(bhp, BH_LOCKED)) {		F_SET(bhp, BH_LOCKED);		MUTEX_LOCK(dbenv, &bhp->mutex);		MUTEX_UNLOCK(dbenv, &hp->hash_mutex);	}	/*	 * It's possible that the underlying file doesn't exist, either	 * because of an outright removal or because it was a temporary	 * file that's been closed.	 *	 * !!!	 * Once we pass this point, we know that dbmfp and mfp aren't NULL,	 * and that we have a valid file reference.	 */	if (mfp == NULL || F_ISSET(mfp, MP_DEADFILE))		goto file_dead;	/*

⌨️ 快捷键说明

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