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

📄 qam_files.c

📁 这是国外的resip协议栈
💻 C
📖 第 1 页 / 共 2 页
字号:
			array->low_extent++;	} else {		if (extid == array->hi_extent)			array->hi_extent--;	}err:	MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);#ifdef CONFIG_TEST	if (real_name != NULL)		__os_free(dbenv, real_name);#endif	return (ret);}/* * __qam_sync -- *	Flush the database cache. * * PUBLIC: int __qam_sync __P((DB *)); */int__qam_sync(dbp)	DB *dbp;{	DB_ENV *dbenv;	DB_MPOOLFILE *mpf;	dbenv = dbp->dbenv;	mpf = dbp->mpf;	/*	 * We need to flush all extent files.  There is no easy way to find	 * all the extents for this queue which are currently open. For now	 * just flush the whole cache.  An alternative would be to have a	 * call into the cache layer that would flush all of the queue extent	 * files it has open (there's a flag when we open a queue extent file,	 * so the cache layer can identify them).	 */	if (((QUEUE *)dbp->q_internal)->page_ext == 0)		return (__memp_fsync(mpf));	else		return (__memp_sync(dbenv, NULL));}/* * __qam_gen_filelist -- generate a list of extent files. *	Another thread may close the handle so this should only *	be used single threaded or with care. * * PUBLIC: int __qam_gen_filelist __P(( DB *, QUEUE_FILELIST **)); */int__qam_gen_filelist(dbp, filelistp)	DB *dbp;	QUEUE_FILELIST **filelistp;{	DB_ENV *dbenv;	DB_MPOOLFILE *mpf;	QUEUE *qp;	QMETA *meta;	size_t extent_cnt;	db_recno_t i, current, first, stop, rec_extent;	QUEUE_FILELIST *fp;	int ret;	dbenv = dbp->dbenv;	mpf = dbp->mpf;	qp = (QUEUE *)dbp->q_internal;	*filelistp = NULL;	if (qp->page_ext == 0)		return (0);	/* This may happen during metapage recovery. */	if (qp->name == NULL)		return (0);	/* Find out the first and last record numbers in the database. */	i = PGNO_BASE_MD;	if ((ret = __memp_fget(mpf, &i, 0, &meta)) != 0)		return (ret);	current = meta->cur_recno;	first = meta->first_recno;	if ((ret = __memp_fput(mpf, meta, 0)) != 0)		return (ret);	/*	 * Allocate the extent array.  Calculate the worst case number of	 * pages and convert that to a count of extents.   The count of	 * extents has 3 or 4 extra slots:	 *   roundoff at first (e.g., current record in extent);	 *   roundoff at current (e.g., first record in extent);	 *   NULL termination; and	 *   UINT32_MAX wraparound (the last extent can be small).	 */	rec_extent = qp->rec_page * qp->page_ext;	if (current >= first)		extent_cnt = (current - first) / rec_extent + 3;	else		extent_cnt =		    (current + (UINT32_MAX - first)) / rec_extent + 4;	if ((ret = __os_calloc(dbenv,	    extent_cnt, sizeof(QUEUE_FILELIST), filelistp)) != 0)		return (ret);	fp = *filelistp;again:	if (current >= first)		stop = current;	else		stop = UINT32_MAX;	/*	 * Make sure that first is at the same offset in the extent as stop.	 * This guarantees that the stop will be reached in the loop below,	 * even if it is the only record in its extent.  This calculation is	 * safe because first won't move out of its extent.	 */	first -= first % rec_extent;	first += stop % rec_extent;	for (i = first; i >= first && i <= stop; i += rec_extent) {		if ((ret = __qam_fprobe(dbp, QAM_RECNO_PAGE(dbp, i), &fp->mpf,		    QAM_PROBE_MPF, 0)) != 0) {			if (ret == ENOENT)				continue;			return (ret);		}		fp->id = QAM_RECNO_EXTENT(dbp, i);		fp++;		DB_ASSERT((size_t)(fp - *filelistp) < extent_cnt);	}	if (current < first) {		first = 1;		goto again;	}	return (0);}/* * __qam_extent_names -- generate a list of extent files names. * * PUBLIC: int __qam_extent_names __P((DB_ENV *, char *, char ***)); */int__qam_extent_names(dbenv, name, namelistp)	DB_ENV *dbenv;	char *name;	char ***namelistp;{	DB *dbp;	QUEUE *qp;	QUEUE_FILELIST *filelist, *fp;	size_t len;	int cnt, ret, t_ret;	char buf[MAXPATHLEN], **cp, *freep;	*namelistp = NULL;	filelist = NULL;	if ((ret = db_create(&dbp, dbenv, 0)) != 0)		return (ret);	if ((ret = __db_open(dbp,	    NULL, name, NULL, DB_QUEUE, DB_RDONLY, 0, PGNO_BASE_MD)) != 0)		return (ret);	qp = dbp->q_internal;	if (qp->page_ext == 0)		goto done;	if ((ret = __qam_gen_filelist(dbp, &filelist)) != 0)		goto done;	if (filelist == NULL)		goto done;	cnt = 0;	for (fp = filelist; fp->mpf != NULL; fp++)		cnt++;	/* QUEUE_EXTENT contains extra chars, but add 6 anyway for the int. */	len = (size_t)cnt * (sizeof(**namelistp) +	    strlen(QUEUE_EXTENT) + strlen(qp->dir) + strlen(qp->name) + 6);	if ((ret = __os_malloc(dbp->dbenv, len, namelistp)) != 0)		goto done;	cp = *namelistp;	freep = (char *)(cp + cnt + 1);	for (fp = filelist; fp->mpf != NULL; fp++) {		QAM_EXNAME(qp, fp->id, buf, sizeof(buf));		len = strlen(buf);		*cp++ = freep;		(void)strcpy(freep, buf);		freep += len + 1;	}	*cp = NULL;done:	if (filelist != NULL)		__os_free(dbp->dbenv, filelist);	if ((t_ret = __db_close(dbp, NULL, DB_NOSYNC)) != 0 && ret == 0)		ret = t_ret;	return (ret);}/* * __qam_exid -- *	Generate a fileid for an extent based on the fileid of the main * file.  Since we do not log schema creates/deletes explicitly, the log * never captures the fileid of an extent file.  In order that masters and * replicas have the same fileids (so they can explicitly delete them), we * use computed fileids for the extent files of Queue files. * * An extent file id retains the low order 12 bytes of the file id and * overwrites the dev/inode fields, placing a 0 in the inode field, and * the extent number in the dev field. * * PUBLIC: void __qam_exid __P((DB *, u_int8_t *, u_int32_t)); */void__qam_exid(dbp, fidp, exnum)	DB *dbp;	u_int8_t *fidp;	u_int32_t exnum;{	int i;	u_int8_t *p;	/* Copy the fileid from the master. */	memcpy(fidp, dbp->fileid, DB_FILE_ID_LEN);	/* The first four bytes are the inode or the FileIndexLow; 0 it. */	for (i = sizeof(u_int32_t); i > 0; --i)		*fidp++ = 0;	/* The next four bytes are the dev/FileIndexHigh; insert the exnum . */	for (p = (u_int8_t *)&exnum, i = sizeof(u_int32_t); i > 0; --i)		*fidp++ = *p++;}/* * __qam_nameop -- *	Remove or rename  extent files associated with a particular file. * This is to remove or rename (both in mpool and the file system) any * extent files associated with the given dbp. * This is either called from the QUEUE remove or rename methods or * when undoing a transaction that created the database. * * PUBLIC: int __qam_nameop __P((DB *, DB_TXN *, const char *, qam_name_op)); */int __qam_nameop(dbp, txn, newname, op)	DB *dbp;	DB_TXN *txn;	const char *newname;	qam_name_op op;{	DB_ENV *dbenv;	QUEUE *qp;	size_t exlen, fulllen, len;	u_int8_t fid[DB_FILE_ID_LEN];	u_int32_t exid;	int cnt, i, ret, t_ret;	char buf[MAXPATHLEN], nbuf[MAXPATHLEN], sepsave;	char *endname, *endpath, *exname, *fullname, **names;	char *ndir, *namep, *new, *cp;	dbenv = dbp->dbenv;	qp = (QUEUE *)dbp->q_internal;	cnt = ret = t_ret = 0;	namep = exname = fullname = NULL;	names = NULL;	/* If this isn't a queue with extents, we're done. */	if (qp->page_ext == 0)		return (0);	/*	 * Generate the list of all queue extents for this file (from the	 * file system) and then cycle through removing them and evicting	 * from mpool.  We have two modes of operation here.  If we are	 * undoing log operations, then do not write log records and try	 * to keep going even if we encounter failures in nameop.  If we	 * are in mainline code, then return as soon as we have a problem.	 * Memory allocation errors (__db_appname, __os_malloc) are always	 * considered failure.	 *	 * Set buf to : dir/__dbq.NAME.0 and fullname to HOME/dir/__dbq.NAME.0	 * or, in the case of an absolute path: /dir/__dbq.NAME.0	 */	QAM_EXNAME(qp, 0, buf, sizeof(buf));	if ((ret =	    __db_appname(dbenv, DB_APP_DATA, buf, 0, NULL, &fullname)) != 0)		return (ret);	/* We should always have a path separator here. */	if ((endpath = __db_rpath(fullname)) == NULL) {		ret = EINVAL;		goto err;	}	sepsave = *endpath;	*endpath = '\0';	/*	 * Get the list of all names in the directory and restore the	 * path separator.	 */	if ((ret = __os_dirlist(dbenv, fullname, &names, &cnt)) != 0)		goto err;	*endpath = sepsave;	/* If there aren't any names, don't allocate any space. */	if (cnt == 0)		goto err;	/*	 * Now, make endpath reference the queue extent names upon which	 * we can match.  Then we set the end of the path to be the	 * beginning of the extent number, and we can compare the bytes	 * between endpath and endname (__dbq.NAME.).	 */	endpath++;	endname = strrchr(endpath, '.');	if (endname == NULL) {		ret = EINVAL;		goto err;	}	++endname;	*endname = '\0';	len = strlen(endpath);	fulllen = strlen(fullname);	/* Allocate space for a full extent name.  */	exlen = fulllen + 20;	if ((ret = __os_malloc(dbenv, exlen, &exname)) != 0)		goto err;	ndir = new = NULL;	if (newname != NULL) {		if ((ret = __os_strdup(dbenv, newname, &namep)) != 0)			goto err;		ndir = namep;		if ((new = __db_rpath(namep)) != NULL)			*new++ = '\0';		else {			new = namep;			ndir = PATH_DOT;		}	}	for (i = 0; i < cnt; i++) {		/* Check if this is a queue extent file. */		if (strncmp(names[i], endpath, len) != 0)			continue;		/* Make sure we have all numbers. foo.db vs. foo.db.0. */		for (cp = &names[i][len]; *cp != '\0'; cp++)			if (!isdigit(*cp))				break;		if (*cp != '\0')			continue;		/*		 * We have a queue extent file.  We need to generate its		 * name and its fileid.		 */		exid = (u_int32_t)strtoul(names[i] + len, NULL, 10);		__qam_exid(dbp, fid, exid);		switch (op) {		case QAM_NAME_DISCARD:			snprintf(exname, exlen,			     "%s%s", fullname, names[i] + len);			if ((t_ret = __memp_nameop(dbenv,			    fid, NULL, exname, NULL)) != 0 && ret == 0)				ret = t_ret;			break;		case QAM_NAME_RENAME:			snprintf(nbuf, sizeof(nbuf), QUEUE_EXTENT,			     ndir, PATH_SEPARATOR[0], new, exid);			QAM_EXNAME(qp, exid, buf, sizeof(buf));			if ((ret = __fop_rename(dbenv,			    txn, buf, nbuf, fid, DB_APP_DATA,			    F_ISSET(dbp, DB_AM_NOT_DURABLE) ?			    DB_LOG_NOT_DURABLE : 0)) != 0)				goto err;			break;		case QAM_NAME_REMOVE:			QAM_EXNAME(qp, exid, buf, sizeof(buf));			if ((ret = __fop_remove(dbenv, txn, fid, buf,			    DB_APP_DATA, F_ISSET(dbp, DB_AM_NOT_DURABLE) ?			    DB_LOG_NOT_DURABLE : 0)) != 0)				goto err;			break;		}	}err:	if (fullname != NULL)		__os_free(dbenv, fullname);	if (exname != NULL)		__os_free(dbenv, exname);	if (namep != NULL)		__os_free(dbenv, namep);	if (names != NULL)		__os_dirfree(dbenv, names, cnt);	return (ret);}

⌨️ 快捷键说明

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