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

📄 mp_fopen.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 2 页
字号:
				ret = EINVAL;				goto err;			}		}		/*		 * If the user specifies DB_MPOOL_LAST or DB_MPOOL_NEW on a		 * page get, we have to increment the last page in the file.		 * Figure it out and save it away.		 *		 * Note correction: page numbers are zero-based, not 1-based.		 */		last_pgno = (db_pgno_t)(mbytes * (MEGABYTE / pagesize));		last_pgno += (db_pgno_t)(bytes / pagesize);		if (last_pgno != 0)			--last_pgno;		mfp->orig_last_pgno = mfp->last_pgno = last_pgno;		/* Copy the file path into shared memory. */		if ((ret = __memp_alloc(dbmp, dbmp->reginfo,		    NULL, strlen(path) + 1, &mfp->path_off, &p)) != 0)			goto err;		memcpy(p, path, strlen(path) + 1);		/* Copy the file identification string into shared memory. */		if ((ret = __memp_alloc(dbmp, dbmp->reginfo,		    NULL, DB_FILE_ID_LEN, &mfp->fileid_off, &p)) != 0)			goto err;		memcpy(p, dbmfp->fileid, DB_FILE_ID_LEN);	}	/* Copy the page cookie into shared memory. */	if (dbmfp->pgcookie == NULL || dbmfp->pgcookie->size == 0) {		mfp->pgcookie_len = 0;		mfp->pgcookie_off = 0;	} else {		if ((ret = __memp_alloc(dbmp, dbmp->reginfo,		    NULL, dbmfp->pgcookie->size, &mfp->pgcookie_off, &p)) != 0)			goto err;		memcpy(p, dbmfp->pgcookie->data, dbmfp->pgcookie->size);		mfp->pgcookie_len = dbmfp->pgcookie->size;	}	/*	 * Prepend the MPOOLFILE to the list of MPOOLFILE's.	 */	R_LOCK(dbenv, dbmp->reginfo);	ret = __db_mutex_setup(dbenv, dbmp->reginfo, &mfp->mutex,	    MUTEX_NO_RLOCK);	if (ret == 0)		SH_TAILQ_INSERT_HEAD(&mp->mpfq, mfp, q, __mpoolfile);	R_UNLOCK(dbenv, dbmp->reginfo);	if (ret != 0)		goto err;check_map:	/*	 * If a file:	 *	+ isn't temporary	 *	+ is read-only	 *	+ doesn't require any pgin/pgout support	 *	+ the DB_NOMMAP flag wasn't set (in either the file open or	 *	  the environment in which it was opened)	 *	+ and is less than mp_mmapsize bytes in size	 *	 * we can mmap it instead of reading/writing buffers.  Don't do error	 * checking based on the mmap call failure.  We want to do normal I/O	 * on the file if the reason we failed was because the file was on an	 * NFS mounted partition, and we can fail in buffer I/O just as easily	 * as here.	 *	 * We'd like to test to see if the file is too big to mmap.  Since we	 * don't know what size or type off_t's or size_t's are, or the largest	 * unsigned integral type is, or what random insanity the local C	 * compiler will perpetrate, doing the comparison in a portable way is	 * flatly impossible.  Hope that mmap fails if the file is too large.	 */#define	DB_MAXMMAPSIZE	(10 * 1024 * 1024)	/* 10 MB. */	if (F_ISSET(mfp, MP_CAN_MMAP)) {		if (path == NULL)			F_CLR(mfp, MP_CAN_MMAP);		if (!F_ISSET(dbmfp, MP_READONLY))			F_CLR(mfp, MP_CAN_MMAP);		if (dbmfp->ftype != 0)			F_CLR(mfp, MP_CAN_MMAP);		if (LF_ISSET(DB_NOMMAP) || F_ISSET(dbenv, DB_ENV_NOMMAP))			F_CLR(mfp, MP_CAN_MMAP);		maxmap = dbenv->mp_mmapsize == 0 ?		    DB_MAXMMAPSIZE : dbenv->mp_mmapsize;		if (mbytes > maxmap / MEGABYTE ||		    (mbytes == maxmap / MEGABYTE && bytes >= maxmap % MEGABYTE))			F_CLR(mfp, MP_CAN_MMAP);		dbmfp->addr = NULL;		if (F_ISSET(mfp, MP_CAN_MMAP)) {			dbmfp->len = (size_t)mbytes * MEGABYTE + bytes;			if (__os_mapfile(dbenv, rpath,			    dbmfp->fhp, dbmfp->len, 1, &dbmfp->addr) != 0) {				dbmfp->addr = NULL;				F_CLR(mfp, MP_CAN_MMAP);			}		}	}	dbmfp->mfp = mfp;	F_SET(dbmfp, MP_OPEN_CALLED);	/* Add the file to the process' list of DB_MPOOLFILEs. */	MUTEX_THREAD_LOCK(dbenv, dbmp->mutexp);	TAILQ_INSERT_TAIL(&dbmp->dbmfq, dbmfp, q);	MUTEX_THREAD_UNLOCK(dbenv, dbmp->mutexp);	if (0) {err:		if (F_ISSET(dbmfp->fhp, DB_FH_VALID))			(void)__os_closehandle(dbenv, dbmfp->fhp);		if (mfp_alloc) {			R_LOCK(dbenv, dbmp->reginfo);			if (mfp->path_off != 0)				__db_shalloc_free(dbmp->reginfo[0].addr,				    R_ADDR(dbmp->reginfo, mfp->path_off));			if (mfp->fileid_off != 0)				__db_shalloc_free(dbmp->reginfo[0].addr,				    R_ADDR(dbmp->reginfo, mfp->fileid_off));			__db_shalloc_free(dbmp->reginfo[0].addr, mfp);			R_UNLOCK(dbenv, dbmp->reginfo);		}	}	if (rpath != NULL)		__os_free(dbenv, rpath);	return (ret);}/* * __memp_get_fileid -- *	Return the file ID. * * XXX * Undocumented interface: DB private. */static void__memp_get_fileid(dbmfp, fidp)	DB_MPOOLFILE *dbmfp;	u_int8_t *fidp;{	/*	 * No lock needed -- we're using the handle, it had better not	 * be going away.	 *	 * !!!	 * Get the fileID out of the region, not out of the DB_MPOOLFILE	 * structure because the DB_MPOOLFILE reference is possibly short	 * lived, and isn't to be trusted.	 */	memcpy(fidp, R_ADDR(	    dbmfp->dbmp->reginfo, dbmfp->mfp->fileid_off), DB_FILE_ID_LEN);}/* * __memp_last_pgno -- *	Return the page number of the last page in the file. * * XXX * Undocumented interface: DB private. */static void__memp_last_pgno(dbmfp, pgnoaddr)	DB_MPOOLFILE *dbmfp;	db_pgno_t *pgnoaddr;{	DB_ENV *dbenv;	DB_MPOOL *dbmp;	dbmp = dbmfp->dbmp;	dbenv = dbmp->dbenv;	R_LOCK(dbenv, dbmp->reginfo);	*pgnoaddr = dbmfp->mfp->last_pgno;	R_UNLOCK(dbenv, dbmp->reginfo);}/* * __memp_refcnt -- *	Return the current reference count. * * XXX * Undocumented interface: DB private. */static void__memp_refcnt(dbmfp, cntp)	DB_MPOOLFILE *dbmfp;	db_pgno_t *cntp;{	DB_ENV *dbenv;	dbenv = dbmfp->dbmp->dbenv;	MUTEX_LOCK(dbenv, &dbmfp->mfp->mutex);	*cntp = dbmfp->mfp->mpf_cnt;	MUTEX_UNLOCK(dbenv, &dbmfp->mfp->mutex);}/* * __memp_set_unlink -- *	Set unlink on last close flag. * * XXX * Undocumented interface: DB private. */static void__memp_set_unlink(dbmpf, set)	DB_MPOOLFILE *dbmpf;	int set;{	DB_ENV *dbenv;	dbenv = dbmpf->dbmp->dbenv;	MUTEX_LOCK(dbenv, &dbmpf->mfp->mutex);	if (set)		F_SET(dbmpf->mfp, MP_UNLINK);	else		F_CLR(dbmpf->mfp, MP_UNLINK);	MUTEX_UNLOCK(dbenv, &dbmpf->mfp->mutex);}/* * memp_fclose -- *	Close a backing file for the memory pool. */static int__memp_fclose(dbmfp, flags)	DB_MPOOLFILE *dbmfp;	u_int32_t flags;{	DB_ENV *dbenv;	int ret, t_ret;	dbenv = dbmfp->dbmp->dbenv;	PANIC_CHECK(dbenv);	/*	 * XXX	 * DB_MPOOL_DISCARD: Undocumented flag: DB private.	 */	ret = __db_fchk(dbenv, "DB_MPOOLFILE->close", flags, DB_MPOOL_DISCARD);	if ((t_ret = __memp_fclose_int(dbmfp, flags)) != 0 && ret == 0)		ret = t_ret;	return (ret);}/* * __memp_fclose_int -- *	Internal version of __memp_fclose. * * PUBLIC: int __memp_fclose_int __P((DB_MPOOLFILE *, u_int32_t)); */int__memp_fclose_int(dbmfp, flags)	DB_MPOOLFILE *dbmfp;	u_int32_t flags;{	DB_ENV *dbenv;	DB_MPOOL *dbmp;	MPOOLFILE *mfp;	char *rpath;	int deleted, ret, t_ret;	dbmp = dbmfp->dbmp;	dbenv = dbmp->dbenv;	ret = 0;	/*	 * We have to reference count DB_MPOOLFILE structures as other threads	 * in the process may be using them.  Here's the problem:	 *	 * Thread A opens a database.	 * Thread B uses thread A's DB_MPOOLFILE to write a buffer	 *    in order to free up memory in the mpool cache.	 * Thread A closes the database while thread B is using the	 *    DB_MPOOLFILE structure.	 *	 * By opening all databases before creating any threads, and closing	 * the databases after all the threads have exited, applications get	 * better performance and avoid the problem path entirely.	 *	 * Regardless, holding the DB_MPOOLFILE to flush a dirty buffer is a	 * short-term lock, even in worst case, since we better be the only	 * thread of control using the DB_MPOOLFILE structure to read pages	 * *into* the cache.  Wait until we're the only reference holder and	 * remove the DB_MPOOLFILE structure from the list, so nobody else can	 * find it.  We do this, rather than have the last reference holder	 * (whoever that might be) discard the DB_MPOOLFILE structure, because	 * we'd rather write error messages to the application in the close	 * routine, not in the checkpoint/sync routine.	 *	 * !!!	 * It's possible the DB_MPOOLFILE was never added to the DB_MPOOLFILE	 * file list, check the DB_OPEN_CALLED flag to be sure.	 */	for (deleted = 0;;) {		MUTEX_THREAD_LOCK(dbenv, dbmp->mutexp);		if (dbmfp->ref == 1) {			if (F_ISSET(dbmfp, MP_OPEN_CALLED))				TAILQ_REMOVE(&dbmp->dbmfq, dbmfp, q);			deleted = 1;		}		MUTEX_THREAD_UNLOCK(dbenv, dbmp->mutexp);		if (deleted)			break;		__os_sleep(dbenv, 1, 0);	}	/* Complain if pinned blocks never returned. */	if (dbmfp->pinref != 0) {		__db_err(dbenv, "%s: close: %lu blocks left pinned",		    __memp_fn(dbmfp), (u_long)dbmfp->pinref);		ret = __db_panic(dbenv, DB_RUNRECOVERY);	}	/* Discard any mmap information. */	if (dbmfp->addr != NULL &&	    (ret = __os_unmapfile(dbenv, dbmfp->addr, dbmfp->len)) != 0)		__db_err(dbenv, "%s: %s", __memp_fn(dbmfp), db_strerror(ret));	/* Close the file; temporary files may not yet have been created. */	if (F_ISSET(dbmfp->fhp, DB_FH_VALID) &&	    (t_ret = __os_closehandle(dbenv, dbmfp->fhp)) != 0) {		__db_err(dbenv, "%s: %s", __memp_fn(dbmfp), db_strerror(t_ret));		if (ret == 0)			ret = t_ret;	}	/* Discard the thread mutex. */	if (dbmfp->mutexp != NULL)		__db_mutex_free(dbenv, dbmp->reginfo, dbmfp->mutexp);	/*	 * Discard our reference on the the underlying MPOOLFILE, and close	 * it if it's no longer useful to anyone.  It possible the open of	 * the file never happened or wasn't successful, in which case, mpf	 * will be NULL;	 */	if ((mfp = dbmfp->mfp) == NULL)		goto done;	/*	 * If it's a temp file, all outstanding references belong to unflushed	 * buffers.  (A temp file can only be referenced by one DB_MPOOLFILE).	 * We don't care about preserving any of those buffers, so mark the	 * MPOOLFILE as dead so that even the dirty ones just get discarded	 * when we try to flush them.	 */	deleted = 0;	MUTEX_LOCK(dbenv, &mfp->mutex);	if (--mfp->mpf_cnt == 0 || LF_ISSET(DB_MPOOL_DISCARD)) {		if (LF_ISSET(DB_MPOOL_DISCARD) ||		    F_ISSET(mfp, MP_TEMP | MP_UNLINK))			MPOOLFILE_IGNORE(mfp);		if (F_ISSET(mfp, MP_UNLINK)) {			if ((t_ret = __db_appname(dbmp->dbenv,			    DB_APP_DATA, R_ADDR(dbmp->reginfo,			    mfp->path_off), 0, NULL, &rpath)) != 0 && ret == 0)				ret = t_ret;			if (t_ret == 0) {				if ((t_ret = __os_unlink(				    dbmp->dbenv, rpath) != 0) && ret == 0)					ret = t_ret;				__os_free(dbenv, rpath);			}		}		if (mfp->block_cnt == 0) {			if ((t_ret =			    __memp_mf_discard(dbmp, mfp)) != 0 && ret == 0)				ret = t_ret;			deleted = 1;		}	}	if (deleted == 0)		MUTEX_UNLOCK(dbenv, &mfp->mutex);	/* Discard the DB_MPOOLFILE structure. */done:	__os_free(dbenv, dbmfp->fhp);	__os_free(dbenv, dbmfp);	return (ret);}/* * __memp_mf_discard -- *	Discard an MPOOLFILE. * * PUBLIC: int __memp_mf_discard __P((DB_MPOOL *, MPOOLFILE *)); */int__memp_mf_discard(dbmp, mfp)	DB_MPOOL *dbmp;	MPOOLFILE *mfp;{	DB_ENV *dbenv;	DB_FH fh;	DB_MPOOL_STAT *sp;	MPOOL *mp;	char *rpath;	int ret;	dbenv = dbmp->dbenv;	mp = dbmp->reginfo[0].primary;	ret = 0;	/*	 * Expects caller to be holding the MPOOLFILE mutex.	 *	 * When discarding a file, we have to flush writes from it to disk.	 * The scenario is that dirty buffers from this file need to be	 * flushed to satisfy a future checkpoint, but when the checkpoint	 * calls mpool sync, the sync code won't know anything about them.	 */	if (!F_ISSET(mfp, MP_DEADFILE) &&	    (ret = __db_appname(dbenv, DB_APP_DATA,	    R_ADDR(dbmp->reginfo, mfp->path_off), 0, NULL, &rpath)) == 0) {		if ((ret = __os_open(dbenv, rpath, 0, 0, &fh)) == 0) {			ret = __os_fsync(dbenv, &fh);			(void)__os_closehandle(dbenv, &fh);		}		__os_free(dbenv, rpath);	}	/*	 * We have to release the MPOOLFILE lock before acquiring the region	 * lock so that we don't deadlock.  Make sure nobody ever looks at	 * this structure again.	 */	MPOOLFILE_IGNORE(mfp);	/* Discard the mutex we're holding. */	MUTEX_UNLOCK(dbenv, &mfp->mutex);	/* Delete from the list of MPOOLFILEs. */	R_LOCK(dbenv, dbmp->reginfo);	SH_TAILQ_REMOVE(&mp->mpfq, mfp, q, __mpoolfile);	/* Copy the statistics into the region. */	sp = &mp->stat;	sp->st_cache_hit += mfp->stat.st_cache_hit;	sp->st_cache_miss += mfp->stat.st_cache_miss;	sp->st_map += mfp->stat.st_map;	sp->st_page_create += mfp->stat.st_page_create;	sp->st_page_in += mfp->stat.st_page_in;	sp->st_page_out += mfp->stat.st_page_out;	/* Clear the mutex this MPOOLFILE recorded. */	__db_shlocks_clear(&mfp->mutex, dbmp->reginfo,	    (REGMAINT *)R_ADDR(dbmp->reginfo, mp->maint_off));	/* Free the space. */	if (mfp->path_off != 0)		__db_shalloc_free(dbmp->reginfo[0].addr,		    R_ADDR(dbmp->reginfo, mfp->path_off));	if (mfp->fileid_off != 0)		__db_shalloc_free(dbmp->reginfo[0].addr,		    R_ADDR(dbmp->reginfo, mfp->fileid_off));	if (mfp->pgcookie_off != 0)		__db_shalloc_free(dbmp->reginfo[0].addr,		    R_ADDR(dbmp->reginfo, mfp->pgcookie_off));	__db_shalloc_free(dbmp->reginfo[0].addr, mfp);	R_UNLOCK(dbenv, dbmp->reginfo);	return (ret);}/* * __memp_fn -- *	On errors we print whatever is available as the file name. * * PUBLIC: char * __memp_fn __P((DB_MPOOLFILE *)); */char *__memp_fn(dbmfp)	DB_MPOOLFILE *dbmfp;{	return (__memp_fns(dbmfp->dbmp, dbmfp->mfp));}/* * __memp_fns -- *	On errors we print whatever is available as the file name. * * PUBLIC: char * __memp_fns __P((DB_MPOOL *, MPOOLFILE *)); * */char *__memp_fns(dbmp, mfp)	DB_MPOOL *dbmp;	MPOOLFILE *mfp;{	if (mfp->path_off == 0)		return ((char *)"temporary");	return ((char *)R_ADDR(dbmp->reginfo, mfp->path_off));}

⌨️ 快捷键说明

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