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

📄 fop_util.c

📁 这是国外的resip协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
				ret = EEXIST;			goto err;		}		goto done;	}	/* File does not exist. */	if (!LF_ISSET(DB_CREATE))		goto err;	ret = 0;	/*	 * We need to create file, which means that we need to set up the file,	 * the fileid and the locks.  Then we need to call the appropriate	 * routines to create meta-data pages.	 */	if ((ret = __ENV_LPUT(dbenv, elock, 0)) != 0)		goto err;create:	if (txn != NULL && IS_REP_CLIENT(dbenv)) {		__db_err(dbenv,		    "Transactional create on replication client disallowed");		ret = EINVAL;		goto err;	}	if ((ret = __db_backup_name(dbenv, name, txn, &tmpname)) != 0)		goto err;	if (TXN_ON(dbenv) && txn != NULL &&	    (ret = __txn_begin(dbenv, txn, &stxn, 0)) != 0)		goto err;	if ((ret = __fop_create(dbenv,	    stxn, &fhp, tmpname, DB_APP_DATA, mode, dflags)) != 0) {		/*		 * If we don't have transactions there is a race on		 * creating the temp file.		 */		if (!TXN_ON(dbenv) && ret == EEXIST) {			__os_free(dbenv, tmpname);			tmpname = NULL;			__os_yield(dbenv, 1);			goto retry;		}		goto err;	}	tmp_created = 1;creat2:	if ((ret = __db_appname(dbenv,	    DB_APP_DATA, tmpname, 0, NULL, &real_tmpname)) != 0)		goto err;	/* Set the pagesize if it isn't yet set. */	if (dbp->pgsize == 0 &&	    (ret = __fop_set_pgsize(dbp, fhp, real_tmpname)) != 0)		goto errmsg;	/* Construct a file_id. */	if ((ret = __os_fileid(dbenv, real_tmpname, 1, dbp->fileid)) != 0)		goto errmsg;	if ((ret = __db_new_file(dbp, stxn, fhp, tmpname)) != 0)		goto err;	/*	 * We need to close the handle here on platforms where remove and	 * rename fail if a handle is open (including Windows).	 */	CLOSE_HANDLE(dbp, fhp);	/*	 * Now move the file into place unless we are creating in place (because	 * we created a database in a file that started out 0-length).	 */	if (!F_ISSET(dbp, DB_AM_COMPENSATE) && !F_ISSET(dbp, DB_AM_RECOVER))		GET_ENVLOCK(dbenv, locker, &elock);	if (F_ISSET(dbp, DB_AM_IN_RENAME)) {		F_CLR(dbp, DB_AM_IN_RENAME);		__txn_remrem(dbenv, txn, real_name);	} else if (name == tmpname) {		/* We created it in place. */	} else if (__os_exists(real_name, NULL) == 0) {		/*		 * Someone managed to create the file; remove our temp		 * and try to open the file that now exists.		 */		(void)__fop_remove(dbenv,		    NULL, dbp->fileid, tmpname, DB_APP_DATA, dflags);		(void)__ENV_LPUT(dbenv, dbp->handle_lock, 0);		LOCK_INIT(dbp->handle_lock);		if (stxn != NULL) {			ret = __txn_abort(stxn);			stxn = NULL;		}		if (ret != 0)			goto err;		goto reopen;	}	if ((ret = __fop_lock_handle(dbenv,	    dbp, locker, DB_LOCK_WRITE, &elock, NOWAIT_FLAG(txn))) != 0)		goto err;	if (tmpname != name && (ret = __fop_rename(dbenv,	    stxn, tmpname, name, dbp->fileid, DB_APP_DATA, dflags)) != 0)		goto err;	if (stxn != NULL) {		*retidp = stxn->txnid;		ret = __txn_commit(stxn, 0);		stxn = NULL;	} else		*retidp = TXN_INVALID;	if (ret != 0)		goto err;	F_SET(dbp, DB_AM_CREATED);	if (0) {errmsg:		__db_err(dbenv, "%s: %s", name, db_strerror(ret));err:		CLOSE_HANDLE(dbp, fhp);		if (stxn != NULL)			(void)__txn_abort(stxn);		if (tmp_created && txn == NULL)			(void)__fop_remove(dbenv,			    NULL, NULL, tmpname, DB_APP_DATA, dflags);		if (txn == NULL)			(void)__ENV_LPUT(dbenv, dbp->handle_lock, 0);		(void)__ENV_LPUT(dbenv, elock, 0);		if (created_locker) {			(void)__lock_id_free(dbenv, dbp->lid);			dbp->lid = DB_LOCK_INVALIDID;		}	}done:	/*	 * There are cases where real_name and tmpname take on the	 * exact same string, so we need to make sure that we do not	 * free twice.	 */	if (!truncating && tmpname != NULL && tmpname != name)		__os_free(dbenv, tmpname);	if (real_name != NULL)		__os_free(dbenv, real_name);	if (real_tmpname != NULL)		__os_free(dbenv, real_tmpname);	CLOSE_HANDLE(dbp, fhp);	return (ret);}/* * __fop_set_pgsize -- *	Set the page size based on file information. */static int__fop_set_pgsize(dbp, fhp, name)	DB *dbp;	DB_FH *fhp;	const char *name;{	DB_ENV *dbenv;	u_int32_t iopsize;	int ret;	dbenv = dbp->dbenv;	/*	 * Use the filesystem's optimum I/O size as the pagesize if a pagesize	 * not specified.  Some filesystems have 64K as their optimum I/O size,	 * but as that results in fairly large default caches, we limit the	 * default pagesize to 16K.	 */	if ((ret = __os_ioinfo(dbenv, name, fhp, NULL, NULL, &iopsize)) != 0) {		__db_err(dbenv, "%s: %s", name, db_strerror(ret));		return (ret);	}	if (iopsize < 512)		iopsize = 512;	if (iopsize > 16 * 1024)		iopsize = 16 * 1024;	/*	 * Sheer paranoia, but we don't want anything that's not a power-of-2	 * (we rely on that for alignment of various types on the pages), and	 * we want a multiple of the sector size as well.  If the value	 * we got out of __os_ioinfo looks bad, use a default instead.	 */	if (!IS_VALID_PAGESIZE(iopsize))		iopsize = DB_DEF_IOSIZE;	dbp->pgsize = iopsize;	F_SET(dbp, DB_AM_PGDEF);	return (0);}/* * __fop_subdb_setup -- * * Subdb setup is significantly simpler than file setup.  In terms of * locking, for the duration of the operation/transaction, the locks on * the meta-data page will suffice to protect us from simultaneous operations * on the sub-database.  Before we complete the operation though, we'll get a * handle lock on the subdatabase so that on one else can try to remove it * while we've got it open.  We use an object that looks like the meta-data * page lock with a different type (DB_HANDLE_LOCK) for the long-term handle. * locks. * * PUBLIC: int __fop_subdb_setup __P((DB *, DB_TXN *, * PUBLIC:     const char *, const char *, int, u_int32_t)); */int__fop_subdb_setup(dbp, txn, mname, name, mode, flags)	DB *dbp;	DB_TXN *txn;	const char *mname, *name;	int mode;	u_int32_t flags;{	DB *mdbp;	DB_ENV *dbenv;	db_lockmode_t lkmode;	int ret, t_ret;	mdbp = NULL;	dbenv = dbp->dbenv;	if ((ret = __db_master_open(dbp, txn, mname, flags, mode, &mdbp)) != 0)		return (ret);	/*	 * If we created this file, then we need to set the DISCARD flag so	 * that if we fail in the middle of this routine, we discard from the	 * mpool any pages that we just created.	 */	if (F_ISSET(mdbp, DB_AM_CREATED))		F_SET(mdbp, DB_AM_DISCARD);	/*	 * We are going to close this instance of the master, so we can	 * steal its handle instead of reopening a handle on the database.	 */	if (LF_ISSET(DB_FCNTL_LOCKING)) {		dbp->saved_open_fhp = mdbp->saved_open_fhp;		mdbp->saved_open_fhp = NULL;	}	/* Copy the pagesize and set the sub-database flag. */	dbp->pgsize = mdbp->pgsize;	F_SET(dbp, DB_AM_SUBDB);	if (name != NULL && (ret = __db_master_update(mdbp, dbp, txn,	    name, dbp->type, MU_OPEN, NULL, flags)) != 0)		goto err;	/*	 * Hijack the master's locker ID as well, so that our locks don't	 * conflict with the master's.  Since we're closing the master,	 * that lid would just have been freed anyway.  Once we've gotten	 * the locker id, we need to acquire the handle lock for this	 * subdatabase.	 */	dbp->lid = mdbp->lid;	mdbp->lid = DB_LOCK_INVALIDID;	DB_TEST_RECOVERY(dbp, DB_TEST_POSTLOG, ret, mname);	/*	 * We copy our fileid from our master so that we all open	 * the same file in mpool.  We'll use the meta-pgno to lock	 * so that we end up with different handle locks.	 */	memcpy(dbp->fileid, mdbp->fileid, DB_FILE_ID_LEN);	lkmode = F_ISSET(dbp, DB_AM_CREATED) || LF_ISSET(DB_WRITEOPEN) ?	    DB_LOCK_WRITE : DB_LOCK_READ;	if ((ret = __fop_lock_handle(dbenv, dbp,	    txn == NULL ? dbp->lid : txn->txnid, lkmode, NULL,	    NOWAIT_FLAG(txn))) != 0)		goto err;	if ((ret = __db_init_subdb(mdbp, dbp, name, txn)) != 0) {		/*		 * If there was no transaction and we created this database,		 * then we need to undo the update of the master database.		 */		if (F_ISSET(dbp, DB_AM_CREATED) && txn != NULL)			(void)__db_master_update(mdbp, dbp, txn,			    name, dbp->type, MU_REMOVE, NULL, 0);		F_CLR(dbp, DB_AM_CREATED);		goto err;	}	/*	 * XXX	 * This should have been done at the top of this routine.  The problem	 * is that __db_init_subdb() uses "standard" routines to process the	 * meta-data page and set information in the DB handle based on it.	 * Those routines have to deal with swapped pages and will normally set	 * the DB_AM_SWAP flag.  However, we use the master's metadata page and	 * that has already been swapped, so they get the is-swapped test wrong.	 */	F_CLR(dbp, DB_AM_SWAP);	F_SET(dbp, F_ISSET(mdbp, DB_AM_SWAP));	/*	 * In the file create case, these happen in separate places so we have	 * two different tests.  They end up in the same place for subdbs, but	 * for compatibility with file testing, we put them both here anyway.	 */	DB_TEST_RECOVERY(dbp, DB_TEST_POSTLOGMETA, ret, mname);	DB_TEST_RECOVERY(dbp, DB_TEST_POSTSYNC, ret, mname);	/*	 * File exists and we have the appropriate locks; we should now	 * process a normal open.	 */	if (F_ISSET(mdbp, DB_AM_CREATED)) {		F_SET(dbp, DB_AM_CREATED_MSTR);		F_CLR(mdbp, DB_AM_DISCARD);	}	if (0) {err:DB_TEST_RECOVERY_LABEL		if (txn == NULL)			(void)__ENV_LPUT(dbenv, dbp->handle_lock, 0);	}	/*	 * The master's handle lock is under the control of the	 * subdb (it acquired the master's locker).  We want to	 * keep the master's handle lock so that no one can remove	 * the file while the subdb is open.  If we register the	 * trade event and then invalidate the copy of the lock	 * in the master's handle, that will accomplish this.  However,	 * before we register this event, we'd better remove any	 * events that we've already registered for the master.	 */	if (!F_ISSET(dbp, DB_AM_RECOVER) && txn != NULL) {		/* Unregister old master events. */		 __txn_remlock(dbenv,		    txn, &mdbp->handle_lock, DB_LOCK_INVALIDID);		/* Now register the new event. */		if ((t_ret = __txn_lockevent(dbenv, txn, dbp,		    &mdbp->handle_lock, dbp->lid == DB_LOCK_INVALIDID ?		    mdbp->lid : dbp->lid)) != 0 && ret == 0)			ret = t_ret;	}	LOCK_INIT(mdbp->handle_lock);	/*	 * If the master was created, we need to sync so that the metadata	 * page is correct on disk for recovery, since it isn't read through	 * mpool.  If we're opening a subdb in an existing file, we can skip	 * the sync.	 */	if ((t_ret =__db_close(mdbp, txn,	    F_ISSET(dbp, DB_AM_CREATED_MSTR) ? 0 : DB_NOSYNC)) != 0 &&	    ret == 0)		ret = t_ret;	return (ret);}/* * __fop_remove_setup -- *	Open handle appropriately and lock for removal of a database file. * * PUBLIC: int __fop_remove_setup __P((DB *, * PUBLIC:      DB_TXN *, const char *, u_int32_t)); */int__fop_remove_setup(dbp, txn, name, flags)	DB *dbp;	DB_TXN *txn;	const char *name;	u_int32_t flags;{	DB_ENV *dbenv;	DB_FH *fhp;	DB_LOCK elock;	u_int32_t refcnt;	u_int8_t mbuf[DBMETASIZE];	int ret;	COMPQUIET(flags, 0);	dbenv = dbp->dbenv;	PANIC_CHECK(dbenv);	LOCK_INIT(elock);	fhp = NULL;	/* Create locker if necessary. */retry:	if (LOCKING_ON(dbenv)) {		if (txn != NULL)

⌨️ 快捷键说明

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