Exemplo n.º 1
0
Arquivo: lock.c Projeto: hef/samba
static int tdb_lock_list(struct tdb_context *tdb, int list, int ltype,
			 enum tdb_lock_flags waitflag)
{
	int ret;
	bool check = false;

	if (tdb->allrecord_lock.count) {
		return tdb_lock_covered_by_allrecord_lock(tdb, ltype);
	}

	/*
	 * Check for recoveries: Someone might have kill -9'ed a process
	 * during a commit.
	 */
	check = !have_data_locks(tdb);
	ret = tdb_nest_lock(tdb, lock_offset(list), ltype, waitflag);

	if (ret == 0 && check && tdb_needs_recovery(tdb)) {
		tdb_nest_unlock(tdb, lock_offset(list), ltype, false);

		if (tdb_lock_and_recover(tdb) == -1) {
			return -1;
		}
		return tdb_lock_list(tdb, list, ltype, waitflag);
	}
	return ret;
}
Exemplo n.º 2
0
Arquivo: lock.c Projeto: hef/samba
_PUBLIC_ int tdb_unlock(struct tdb_context *tdb, int list, int ltype)
{
	/* a global lock allows us to avoid per chain locks */
	if (tdb->allrecord_lock.count) {
		return tdb_lock_covered_by_allrecord_lock(tdb, ltype);
	}

	return tdb_nest_unlock(tdb, lock_offset(list), ltype, false);
}
Exemplo n.º 3
0
Arquivo: tdb.c Projeto: GSam/samba
/*
  increment the tdb sequence number if the tdb has been opened using
  the TDB_SEQNUM flag
*/
static void tdb_increment_seqnum(struct tdb_context *tdb)
{
	if (!(tdb->flags & TDB_SEQNUM)) {
		return;
	}

	if (tdb->transaction != NULL) {
		tdb_increment_seqnum_nonblock(tdb);
		return;
	}

	if (tdb_nest_lock(tdb, TDB_SEQNUM_OFS, F_WRLCK,
			  TDB_LOCK_WAIT|TDB_LOCK_PROBE) != 0) {
		return;
	}

	tdb_increment_seqnum_nonblock(tdb);

	tdb_nest_unlock(tdb, TDB_SEQNUM_OFS, F_WRLCK, false);
}
Exemplo n.º 4
0
Arquivo: lock.c Projeto: hef/samba
_PUBLIC_ int tdb_transaction_write_lock_unmark(struct tdb_context *tdb)
{
	return tdb_nest_unlock(tdb, TRANSACTION_LOCK, F_WRLCK, true);
}
Exemplo n.º 5
0
Arquivo: lock.c Projeto: hef/samba
/* unmark a chain as locked without actually locking it. Warning! use with great caution! */
_PUBLIC_ int tdb_chainlock_unmark(struct tdb_context *tdb, TDB_DATA key)
{
	tdb_trace_1rec(tdb, "tdb_chainlock_unmark", key);
	return tdb_nest_unlock(tdb, lock_offset(BUCKET(tdb->hash_fn(&key))),
			       F_WRLCK, true);
}
Exemplo n.º 6
0
Arquivo: lock.c Projeto: hef/samba
/*
  release the transaction lock
 */
int tdb_transaction_unlock(struct tdb_context *tdb, int ltype)
{
	return tdb_nest_unlock(tdb, TRANSACTION_LOCK, ltype, false);
}
Exemplo n.º 7
0
Arquivo: open.c Projeto: hef/samba
static bool tdb_mutex_open_ok(struct tdb_context *tdb,
			      const struct tdb_header *header)
{
	int locked;

	locked = tdb_nest_lock(tdb, ACTIVE_LOCK, F_WRLCK,
			       TDB_LOCK_NOWAIT|TDB_LOCK_PROBE);

	if ((locked == -1) && (tdb->ecode == TDB_ERR_LOCK)) {
		/*
		 * CLEAR_IF_FIRST still active. The tdb was created on this
		 * host, so we can assume the mutex implementation is
		 * compatible. Important for tools like tdbdump on a still
		 * open locking.tdb.
		 */
		goto check_local_settings;
	}

	/*
	 * We got the CLEAR_IF_FIRST lock. That means the database was
	 * potentially copied from somewhere else. The mutex implementation
	 * might be incompatible.
	 */

	if (tdb_nest_unlock(tdb, ACTIVE_LOCK, F_WRLCK, false) == -1) {
		/*
		 * Should not happen
		 */
		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_mutex_open_ok: "
			 "failed to release ACTIVE_LOCK on %s: %s\n",
			 tdb->name, strerror(errno)));
		return false;
	}

	if (tdb->flags & TDB_NOLOCK) {
		/*
		 * We don't look at locks, so it does not matter to have a
		 * compatible mutex implementation. Allow the open.
		 */
		return true;
	}

check_local_settings:

	if (!(tdb->flags & TDB_MUTEX_LOCKING)) {
		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_mutex_open_ok[%s]: "
			 "Can use mutexes only with "
			 "MUTEX_LOCKING or NOLOCK\n",
			 tdb->name));
		return false;
	}

	if (tdb_mutex_size(tdb) != header->mutex_size) {
		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_mutex_open_ok[%s]: "
			 "Mutex size changed from %u to %u\n.",
			 tdb->name,
			 (unsigned int)header->mutex_size,
			 (unsigned int)tdb_mutex_size(tdb)));
		return false;
	}

	return true;
}