Ejemplo n.º 1
0
/*
  a write style traverse - needs to get the transaction lock to
  prevent deadlocks

  WARNING: The data buffer given to the callback fn does NOT meet the
  alignment guarantees malloc gives you.
*/
_PUBLIC_ int tdb_traverse(struct tdb_context *tdb,
		 tdb_traverse_func fn, void *private_data)
{
	struct tdb_traverse_lock tl = { NULL, 0, 0, F_WRLCK };
	enum tdb_lock_flags lock_flags;
	int ret;

	if (tdb->read_only || tdb->traverse_read) {
		return tdb_traverse_read(tdb, fn, private_data);
	}

	lock_flags = TDB_LOCK_WAIT;

	if (tdb->allrecord_lock.count != 0) {
		/*
		 * This avoids a deadlock between tdb_lockall() and
		 * tdb_traverse(). See
		 * https://bugzilla.samba.org/show_bug.cgi?id=11381
		 */
		lock_flags = TDB_LOCK_NOWAIT;
	}

	if (tdb_transaction_lock(tdb, F_WRLCK, lock_flags)) {
		return -1;
	}

	tdb->traverse_write++;
	tdb_trace(tdb, "tdb_traverse_start");
	ret = tdb_traverse_internal(tdb, fn, private_data, &tl);
	tdb->traverse_write--;

	tdb_transaction_unlock(tdb, F_WRLCK);

	return ret;
}
Ejemplo n.º 2
0
/*
  a write style traverse - needs to get the transaction lock to
  prevent deadlocks

  WARNING: The data buffer given to the callback fn does NOT meet the
  alignment restrictions malloc gives you.
*/
int tdb_traverse(struct tdb_context *tdb, 
		 tdb_traverse_func fn, void *private_data)
{
	struct tdb_traverse_lock tl = { NULL, 0, 0, F_WRLCK };
	int ret;
	bool in_transaction = (tdb->transaction != NULL);

	if (tdb->read_only || tdb->traverse_read) {
		return tdb_traverse_read(tdb, fn, private_data);
	}
	
	if (!in_transaction) {
		if (tdb_transaction_lock(tdb, F_WRLCK)) {
			return -1;
		}
	}

	tdb->traverse_write++;
	ret = tdb_traverse_internal(tdb, fn, private_data, &tl);
	tdb->traverse_write--;

	if (!in_transaction) {
		tdb_transaction_unlock(tdb);
	}

	return ret;
}
Ejemplo n.º 3
0
/*
  a write style traverse - temporarily marks the db read only
*/
int tdb_traverse_read(struct tdb_context *tdb, 
		      tdb_traverse_func fn, void *private_data)
{
	struct tdb_traverse_lock tl = { NULL, 0, 0, F_RDLCK };
	int ret;
	bool in_transaction = (tdb->transaction != NULL);

	/* we need to get a read lock on the transaction lock here to
	   cope with the lock ordering semantics of solaris10 */
	if (!in_transaction) {
		if (tdb_transaction_lock(tdb, F_RDLCK)) {
			return -1;
		}
	}

	tdb->traverse_read++;
	ret = tdb_traverse_internal(tdb, fn, private_data, &tl);
	tdb->traverse_read--;

	if (!in_transaction) {
		tdb_transaction_unlock(tdb);
	}

	return ret;
}
Ejemplo n.º 4
0
/*
  a read style traverse - temporarily marks each record read only
*/
_PUBLIC_ int tdb_traverse_read(struct tdb_context *tdb,
		      tdb_traverse_func fn, void *private_data)
{
	struct tdb_traverse_lock tl = { NULL, 0, 0, F_RDLCK };
	int ret;

	tdb->traverse_read++;
	tdb_trace(tdb, "tdb_traverse_read_start");
	ret = tdb_traverse_internal(tdb, fn, private_data, &tl);
	tdb->traverse_read--;

	return ret;
}
Ejemplo n.º 5
0
/*
  a read style traverse - temporarily marks the db read only
*/
_PUBLIC_ int tdb_traverse_read(struct tdb_context *tdb,
		      tdb_traverse_func fn, void *private_data)
{
	struct tdb_traverse_lock tl = { NULL, 0, 0, F_RDLCK };
	int ret;

	/* we need to get a read lock on the transaction lock here to
	   cope with the lock ordering semantics of solaris10 */
	if (tdb_transaction_lock(tdb, F_RDLCK, TDB_LOCK_WAIT)) {
		return -1;
	}

	tdb->traverse_read++;
	tdb_trace(tdb, "tdb_traverse_read_start");
	ret = tdb_traverse_internal(tdb, fn, private_data, &tl);
	tdb->traverse_read--;

	tdb_transaction_unlock(tdb, F_RDLCK);

	return ret;
}
Ejemplo n.º 6
0
/*
  a write style traverse - needs to get the transaction lock to
  prevent deadlocks
*/
int tdb_traverse(struct tdb_context *tdb, 
		 tdb_traverse_func fn, void *private_data)
{
	struct tdb_traverse_lock tl = { NULL, 0, 0, F_WRLCK };
	int ret;

	if (tdb->read_only || tdb->traverse_read) {
		return tdb_traverse_read(tdb, fn, private_data);
	}
	
	if (tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_WRLCK, F_SETLKW, 0, 1) == -1) {
		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_traverse: failed to get transaction lock\n"));
		tdb->ecode = TDB_ERR_LOCK;
		return -1;
	}

	ret = tdb_traverse_internal(tdb, fn, private_data, &tl);

	tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1);

	return ret;
}
Ejemplo n.º 7
0
/*
  a write style traverse - temporarily marks the db read only
*/
int tdb_traverse_read(struct tdb_context *tdb, 
		      tdb_traverse_func fn, void *private_data)
{
	struct tdb_traverse_lock tl = { NULL, 0, 0, F_RDLCK };
	int ret;
	
	/* we need to get a read lock on the transaction lock here to
	   cope with the lock ordering semantics of solaris10 */
	if (tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_RDLCK, F_SETLKW, 0, 1) == -1) {
		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_traverse_read: failed to get transaction lock\n"));
		tdb->ecode = TDB_ERR_LOCK;
		return -1;
	}

	tdb->traverse_read++;
	ret = tdb_traverse_internal(tdb, fn, private_data, &tl);
	tdb->traverse_read--;

	tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1);

	return ret;
}
Ejemplo n.º 8
0
/*
  a write style traverse - needs to get the transaction lock to
  prevent deadlocks

  WARNING: The data buffer given to the callback fn does NOT meet the
  alignment guarantees malloc gives you.
*/
_PUBLIC_ int tdb_traverse(struct tdb_context *tdb,
		 tdb_traverse_func fn, void *private_data)
{
	struct tdb_traverse_lock tl = { NULL, 0, 0, F_WRLCK };
	int ret;

	if (tdb->read_only || tdb->traverse_read) {
		return tdb_traverse_read(tdb, fn, private_data);
	}

	if (tdb_transaction_lock(tdb, F_WRLCK, TDB_LOCK_WAIT)) {
		return -1;
	}

	tdb->traverse_write++;
	tdb_trace(tdb, "tdb_traverse_start");
	ret = tdb_traverse_internal(tdb, fn, private_data, &tl);
	tdb->traverse_write--;

	tdb_transaction_unlock(tdb, F_WRLCK);

	return ret;
}