mirror of
https://github.com/samba-team/samba.git
synced 2025-01-15 23:24:37 +03:00
Keep the tdb code in sync with Samba4.
Mainly this is the svn changes : ------------------------------------------------------------------------ r23238 | tridge | 2007-05-30 01:15:49 -0700 (Wed, 30 May 2007) | 6 lines merged transaction lock changes from ctdb this ensures that having the global lock also implies the transaction lock ------------------------------------------------------------------------ r22832 | tridge | 2007-05-13 18:00:06 -0700 (Sun, 13 May 2007) | 3 lines merged the latest tdb changes from ctdb to Samba4 Jeremy.
This commit is contained in:
parent
ef8da16983
commit
ab11c00557
@ -12,10 +12,15 @@ libdir = @libdir@
|
||||
VPATH = @srcdir@:@libreplacedir@
|
||||
srcdir = @srcdir@
|
||||
builddir = @builddir@
|
||||
CPPFLAGS = @CPPFLAGS@ -I$(srcdir)/include -Iinclude -I@libreplacedir@
|
||||
CPPFLAGS = @CPPFLAGS@ -I$(srcdir)/include -Iinclude
|
||||
CFLAGS = $(CPPFLAGS) @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
EXEEXT = @EXEEXT@
|
||||
SHLD_FLAGS = @SHLD_FLAGS@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PICFLAG = @PICFLAG@
|
||||
SONAMEFLAG = @SONAMEFLAG@
|
||||
SHLIBEXT = @SHLIBEXT@
|
||||
|
||||
.PHONY: test
|
||||
|
||||
@ -23,11 +28,14 @@ PROGS = bin/tdbtool$(EXEEXT) bin/tdbdump$(EXEEXT) bin/tdbbackup$(EXEEXT)
|
||||
PROGS_NOINSTALL = bin/tdbtest$(EXEEXT) bin/tdbtorture$(EXEEXT)
|
||||
ALL_PROGS = $(PROGS) $(PROGS_NOINSTALL)
|
||||
|
||||
TDB_OBJ = @TDBOBJ@ @LIBREPLACEOBJ@
|
||||
TDB_OBJ = @TDB_OBJ@ @LIBREPLACEOBJ@
|
||||
|
||||
DIRS = bin common tools
|
||||
|
||||
all: showflags dirs $(PROGS)
|
||||
SONAME = libtdb.$(SHLIBEXT).1
|
||||
SOLIB = libtdb.$(SHLIBEXT).$(PACKAGE_VERSION)
|
||||
|
||||
all: showflags dirs $(PROGS) $(SOLIB) libtdb.a
|
||||
|
||||
showflags:
|
||||
@echo 'tdb will be compiled with flags:'
|
||||
@ -36,39 +44,53 @@ showflags:
|
||||
@echo ' LDFLAGS = $(LDFLAGS)'
|
||||
@echo ' LIBS = $(LIBS)'
|
||||
|
||||
.SUFFIXES: .c .o
|
||||
|
||||
.c.o:
|
||||
@echo Compiling $*.c
|
||||
@mkdir -p `dirname $@`
|
||||
@$(CC) $(CFLAGS) -c $< -o $@
|
||||
@$(CC) $(PICFLAG) $(CFLAGS) -c $< -o $@
|
||||
|
||||
dirs:
|
||||
@mkdir -p $(DIRS)
|
||||
|
||||
install: all
|
||||
mkdir -p $(bindir)
|
||||
mkdir -p $(includedir)
|
||||
mkdir -p $(libdir)
|
||||
mkdir -p $(libdir)/pkgconfig
|
||||
cp $(PROGS) $(bindir)
|
||||
cp $(srcdir)/include/tdb.h $(includedir)
|
||||
cp tdb.pc $(libdir)/pkgconfig
|
||||
mkdir -p $(DESTDIR)$(bindir)
|
||||
mkdir -p $(DESTDIR)$(includedir)
|
||||
mkdir -p $(DESTDIR)$(libdir)
|
||||
mkdir -p $(DESTDIR)$(libdir)/pkgconfig
|
||||
cp $(PROGS) $(DESTDIR)$(bindir)
|
||||
cp $(srcdir)/include/tdb.h $(DESTDIR)$(includedir)
|
||||
cp tdb.pc $(DESTDIR)$(libdir)/pkgconfig
|
||||
cp libtdb.a $(SOLIB) $(DESTDIR)$(libdir)
|
||||
|
||||
libtdb.a: $(TDB_OBJ)
|
||||
ar -rv libtdb.a $(TDB_OBJ)
|
||||
|
||||
bin/tdbtest$(EXEEXT): tools/tdbtest.o libtdb.a
|
||||
libtdb.(SHLIBEXT): $(SOLIB)
|
||||
ln -s $< $@
|
||||
|
||||
$(SONAME): $(SOLIB)
|
||||
ln -s $< $@
|
||||
|
||||
$(SOLIB): $(TDB_OBJ)
|
||||
$(CC) $(SHLD_FLAGS) $(SONAMEFLAG)$(SONAME) -o $@ $^
|
||||
|
||||
TDB_LIB = libtdb.a
|
||||
|
||||
bin/tdbtest$(EXEEXT): tools/tdbtest.o $(TDB_LIB)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o bin/tdbtest tools/tdbtest.o -L. -ltdb -lgdbm
|
||||
|
||||
bin/tdbtool$(EXEEXT): tools/tdbtool.o libtdb.a
|
||||
bin/tdbtool$(EXEEXT): tools/tdbtool.o $(TDB_LIB)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o bin/tdbtool tools/tdbtool.o -L. -ltdb
|
||||
|
||||
bin/tdbtorture$(EXEEXT): tools/tdbtorture.o libtdb.a
|
||||
bin/tdbtorture$(EXEEXT): tools/tdbtorture.o $(TDB_LIB)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o bin/tdbtorture tools/tdbtorture.o -L. -ltdb
|
||||
|
||||
bin/tdbdump$(EXEEXT): tools/tdbdump.o libtdb.a
|
||||
bin/tdbdump$(EXEEXT): tools/tdbdump.o $(TDB_LIB)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o bin/tdbdump tools/tdbdump.o -L. -ltdb
|
||||
|
||||
bin/tdbbackup$(EXEEXT): tools/tdbbackup.o libtdb.a
|
||||
bin/tdbbackup$(EXEEXT): tools/tdbbackup.o $(TDB_LIB)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o bin/tdbbackup tools/tdbbackup.o -L. -ltdb
|
||||
|
||||
test: bin/tdbtorture$(EXEEXT)
|
||||
@ -79,6 +101,7 @@ installcheck: test install
|
||||
clean:
|
||||
rm -f $(ALL_PROGS) *.o *.a common/*.o tools/*.o tdb.pc
|
||||
rm -f test.db test.tdb torture.tdb test.gdbm
|
||||
rm -f $(SONAME) $(SOLIB) libtdb.a
|
||||
|
||||
distclean: clean
|
||||
rm -f *~ */*~
|
||||
|
@ -27,6 +27,8 @@
|
||||
|
||||
#include "tdb_private.h"
|
||||
|
||||
#define TDB_MARK_LOCK 0x80000000
|
||||
|
||||
void tdb_setalarm_sigptr(struct tdb_context *tdb, volatile sig_atomic_t *ptr)
|
||||
{
|
||||
tdb->interrupt_sig_ptr = ptr;
|
||||
@ -116,10 +118,13 @@ int tdb_brlock_upgrade(struct tdb_context *tdb, tdb_off_t offset, size_t len)
|
||||
|
||||
|
||||
/* lock a list in the database. list -1 is the alloc list */
|
||||
int tdb_lock(struct tdb_context *tdb, int list, int ltype)
|
||||
static int _tdb_lock(struct tdb_context *tdb, int list, int ltype, int op)
|
||||
{
|
||||
struct tdb_lock_type *new_lck;
|
||||
int i;
|
||||
bool mark_lock = ((ltype & TDB_MARK_LOCK) == TDB_MARK_LOCK);
|
||||
|
||||
ltype &= ~TDB_MARK_LOCK;
|
||||
|
||||
/* a global lock allows us to avoid per chain locks */
|
||||
if (tdb->global_lock.count &&
|
||||
@ -169,10 +174,9 @@ int tdb_lock(struct tdb_context *tdb, int list, int ltype)
|
||||
|
||||
/* Since fcntl locks don't nest, we do a lock for the first one,
|
||||
and simply bump the count for future ones */
|
||||
if (tdb->methods->tdb_brlock(tdb,FREELIST_TOP+4*list,ltype,F_SETLKW,
|
||||
if (!mark_lock &&
|
||||
tdb->methods->tdb_brlock(tdb,FREELIST_TOP+4*list, ltype, op,
|
||||
0, 1)) {
|
||||
TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lock failed on list %d "
|
||||
"ltype=%d (%s)\n", list, ltype, strerror(errno)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -186,6 +190,25 @@ int tdb_lock(struct tdb_context *tdb, int list, int ltype)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* lock a list in the database. list -1 is the alloc list */
|
||||
int tdb_lock(struct tdb_context *tdb, int list, int ltype)
|
||||
{
|
||||
int ret;
|
||||
ret = _tdb_lock(tdb, list, ltype, F_SETLKW);
|
||||
if (ret) {
|
||||
TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lock failed on list %d "
|
||||
"ltype=%d (%s)\n", list, ltype, strerror(errno)));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* lock a list in the database. list -1 is the alloc list. non-blocking lock */
|
||||
int tdb_lock_nonblock(struct tdb_context *tdb, int list, int ltype)
|
||||
{
|
||||
return _tdb_lock(tdb, list, ltype, F_SETLK);
|
||||
}
|
||||
|
||||
|
||||
/* unlock the database: returns void because it's too late for errors. */
|
||||
/* changed to return int it may be interesting to know there
|
||||
has been an error --simo */
|
||||
@ -194,6 +217,9 @@ int tdb_unlock(struct tdb_context *tdb, int list, int ltype)
|
||||
int ret = -1;
|
||||
int i;
|
||||
struct tdb_lock_type *lck = NULL;
|
||||
bool mark_lock = ((ltype & TDB_MARK_LOCK) == TDB_MARK_LOCK);
|
||||
|
||||
ltype &= ~TDB_MARK_LOCK;
|
||||
|
||||
/* a global lock allows us to avoid per chain locks */
|
||||
if (tdb->global_lock.count &&
|
||||
@ -238,8 +264,12 @@ int tdb_unlock(struct tdb_context *tdb, int list, int ltype)
|
||||
* anyway.
|
||||
*/
|
||||
|
||||
ret = tdb->methods->tdb_brlock(tdb, FREELIST_TOP+4*list, F_UNLCK,
|
||||
F_SETLKW, 0, 1);
|
||||
if (mark_lock) {
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = tdb->methods->tdb_brlock(tdb, FREELIST_TOP+4*list, F_UNLCK,
|
||||
F_SETLKW, 0, 1);
|
||||
}
|
||||
tdb->num_locks--;
|
||||
|
||||
/*
|
||||
@ -266,11 +296,50 @@ int tdb_unlock(struct tdb_context *tdb, int list, int ltype)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
get the transaction lock
|
||||
*/
|
||||
int tdb_transaction_lock(struct tdb_context *tdb, int ltype)
|
||||
{
|
||||
if (tdb->have_transaction_lock || tdb->global_lock.count) {
|
||||
return 0;
|
||||
}
|
||||
if (tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, ltype,
|
||||
F_SETLKW, 0, 1) == -1) {
|
||||
TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_lock: failed to get transaction lock\n"));
|
||||
tdb->ecode = TDB_ERR_LOCK;
|
||||
return -1;
|
||||
}
|
||||
tdb->have_transaction_lock = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
release the transaction lock
|
||||
*/
|
||||
int tdb_transaction_unlock(struct tdb_context *tdb)
|
||||
{
|
||||
int ret;
|
||||
if (!tdb->have_transaction_lock) {
|
||||
return 0;
|
||||
}
|
||||
ret = tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1);
|
||||
if (ret == 0) {
|
||||
tdb->have_transaction_lock = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* lock/unlock entire database */
|
||||
static int _tdb_lockall(struct tdb_context *tdb, int ltype)
|
||||
static int _tdb_lockall(struct tdb_context *tdb, int ltype, int op)
|
||||
{
|
||||
bool mark_lock = ((ltype & TDB_MARK_LOCK) == TDB_MARK_LOCK);
|
||||
|
||||
ltype &= ~TDB_MARK_LOCK;
|
||||
|
||||
/* There are no locks on read-only dbs */
|
||||
if (tdb->read_only || tdb->traverse_read)
|
||||
return TDB_ERRCODE(TDB_ERR_LOCK, -1);
|
||||
@ -290,9 +359,12 @@ static int _tdb_lockall(struct tdb_context *tdb, int ltype)
|
||||
return TDB_ERRCODE(TDB_ERR_LOCK, -1);
|
||||
}
|
||||
|
||||
if (tdb->methods->tdb_brlock(tdb, FREELIST_TOP, ltype, F_SETLKW,
|
||||
if (!mark_lock &&
|
||||
tdb->methods->tdb_brlock(tdb, FREELIST_TOP, ltype, op,
|
||||
0, 4*tdb->header.hash_size)) {
|
||||
TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lockall failed (%s)\n", strerror(errno)));
|
||||
if (op == F_SETLKW) {
|
||||
TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lockall failed (%s)\n", strerror(errno)));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -302,9 +374,15 @@ static int _tdb_lockall(struct tdb_context *tdb, int ltype)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* unlock entire db */
|
||||
static int _tdb_unlockall(struct tdb_context *tdb, int ltype)
|
||||
{
|
||||
bool mark_lock = ((ltype & TDB_MARK_LOCK) == TDB_MARK_LOCK);
|
||||
|
||||
ltype &= ~TDB_MARK_LOCK;
|
||||
|
||||
/* There are no locks on read-only dbs */
|
||||
if (tdb->read_only || tdb->traverse_read) {
|
||||
return TDB_ERRCODE(TDB_ERR_LOCK, -1);
|
||||
@ -319,7 +397,8 @@ static int _tdb_unlockall(struct tdb_context *tdb, int ltype)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (tdb->methods->tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW,
|
||||
if (!mark_lock &&
|
||||
tdb->methods->tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW,
|
||||
0, 4*tdb->header.hash_size)) {
|
||||
TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlockall failed (%s)\n", strerror(errno)));
|
||||
return -1;
|
||||
@ -334,7 +413,25 @@ static int _tdb_unlockall(struct tdb_context *tdb, int ltype)
|
||||
/* lock entire database with write lock */
|
||||
int tdb_lockall(struct tdb_context *tdb)
|
||||
{
|
||||
return _tdb_lockall(tdb, F_WRLCK);
|
||||
return _tdb_lockall(tdb, F_WRLCK, F_SETLKW);
|
||||
}
|
||||
|
||||
/* lock entire database with write lock - mark only */
|
||||
int tdb_lockall_mark(struct tdb_context *tdb)
|
||||
{
|
||||
return _tdb_lockall(tdb, F_WRLCK | TDB_MARK_LOCK, F_SETLKW);
|
||||
}
|
||||
|
||||
/* unlock entire database with write lock - unmark only */
|
||||
int tdb_lockall_unmark(struct tdb_context *tdb)
|
||||
{
|
||||
return _tdb_unlockall(tdb, F_WRLCK | TDB_MARK_LOCK);
|
||||
}
|
||||
|
||||
/* lock entire database with write lock - nonblocking varient */
|
||||
int tdb_lockall_nonblock(struct tdb_context *tdb)
|
||||
{
|
||||
return _tdb_lockall(tdb, F_WRLCK, F_SETLK);
|
||||
}
|
||||
|
||||
/* unlock entire database with write lock */
|
||||
@ -346,7 +443,13 @@ int tdb_unlockall(struct tdb_context *tdb)
|
||||
/* lock entire database with read lock */
|
||||
int tdb_lockall_read(struct tdb_context *tdb)
|
||||
{
|
||||
return _tdb_lockall(tdb, F_RDLCK);
|
||||
return _tdb_lockall(tdb, F_RDLCK, F_SETLKW);
|
||||
}
|
||||
|
||||
/* lock entire database with read lock - nonblock varient */
|
||||
int tdb_lockall_read_nonblock(struct tdb_context *tdb)
|
||||
{
|
||||
return _tdb_lockall(tdb, F_RDLCK, F_SETLK);
|
||||
}
|
||||
|
||||
/* unlock entire database with read lock */
|
||||
@ -362,6 +465,26 @@ int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key)
|
||||
return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK);
|
||||
}
|
||||
|
||||
/* lock/unlock one hash chain, non-blocking. This is meant to be used
|
||||
to reduce contention - it cannot guarantee how many records will be
|
||||
locked */
|
||||
int tdb_chainlock_nonblock(struct tdb_context *tdb, TDB_DATA key)
|
||||
{
|
||||
return tdb_lock_nonblock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK);
|
||||
}
|
||||
|
||||
/* mark a chain as locked without actually locking it. Warning! use with great caution! */
|
||||
int tdb_chainlock_mark(struct tdb_context *tdb, TDB_DATA key)
|
||||
{
|
||||
return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK | TDB_MARK_LOCK);
|
||||
}
|
||||
|
||||
/* unmark a chain as locked without actually locking it. Warning! use with great caution! */
|
||||
int tdb_chainlock_unmark(struct tdb_context *tdb, TDB_DATA key)
|
||||
{
|
||||
return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK | TDB_MARK_LOCK);
|
||||
}
|
||||
|
||||
int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key)
|
||||
{
|
||||
return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK);
|
||||
|
@ -30,10 +30,10 @@
|
||||
TDB_DATA tdb_null;
|
||||
|
||||
/*
|
||||
increment the tdb sequence number if the tdb has been opened using
|
||||
non-blocking increment of the tdb sequence number if the tdb has been opened using
|
||||
the TDB_SEQNUM flag
|
||||
*/
|
||||
static void tdb_increment_seqnum(struct tdb_context *tdb)
|
||||
void tdb_increment_seqnum_nonblock(struct tdb_context *tdb)
|
||||
{
|
||||
tdb_off_t seqnum=0;
|
||||
|
||||
@ -41,16 +41,29 @@ static void tdb_increment_seqnum(struct tdb_context *tdb)
|
||||
return;
|
||||
}
|
||||
|
||||
if (tdb_brlock(tdb, TDB_SEQNUM_OFS, F_WRLCK, F_SETLKW, 1, 1) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* we ignore errors from this, as we have no sane way of
|
||||
dealing with them.
|
||||
*/
|
||||
tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum);
|
||||
seqnum++;
|
||||
tdb_ofs_write(tdb, TDB_SEQNUM_OFS, &seqnum);
|
||||
}
|
||||
|
||||
/*
|
||||
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_brlock(tdb, TDB_SEQNUM_OFS, F_WRLCK, F_SETLKW, 1, 1) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
tdb_increment_seqnum_nonblock(tdb);
|
||||
|
||||
tdb_brlock(tdb, TDB_SEQNUM_OFS, F_UNLCK, F_SETLKW, 1, 1);
|
||||
}
|
||||
@ -653,3 +666,11 @@ int tdb_get_flags(struct tdb_context *tdb)
|
||||
return tdb->flags;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
enable sequence number handling on an open tdb
|
||||
*/
|
||||
void tdb_enable_seqnum(struct tdb_context *tdb)
|
||||
{
|
||||
tdb->flags |= TDB_SEQNUM;
|
||||
}
|
||||
|
@ -162,6 +162,7 @@ struct tdb_context {
|
||||
struct tdb_transaction *transaction;
|
||||
int page_size;
|
||||
int max_dead_records;
|
||||
bool have_transaction_lock;
|
||||
volatile sig_atomic_t *interrupt_sig_ptr;
|
||||
};
|
||||
|
||||
@ -174,6 +175,8 @@ void tdb_mmap(struct tdb_context *tdb);
|
||||
int tdb_lock(struct tdb_context *tdb, int list, int ltype);
|
||||
int tdb_unlock(struct tdb_context *tdb, int list, int ltype);
|
||||
int tdb_brlock(struct tdb_context *tdb, tdb_off_t offset, int rw_type, int lck_type, int probe, size_t len);
|
||||
int tdb_transaction_lock(struct tdb_context *tdb, int ltype);
|
||||
int tdb_transaction_unlock(struct tdb_context *tdb);
|
||||
int tdb_brlock_upgrade(struct tdb_context *tdb, tdb_off_t offset, size_t len);
|
||||
int tdb_write_lock_record(struct tdb_context *tdb, tdb_off_t off);
|
||||
int tdb_write_unlock_record(struct tdb_context *tdb, tdb_off_t off);
|
||||
|
@ -422,9 +422,7 @@ int tdb_transaction_start(struct tdb_context *tdb)
|
||||
/* get the transaction write lock. This is a blocking lock. As
|
||||
discussed with Volker, there are a number of ways we could
|
||||
make this async, which we will probably do in the future */
|
||||
if (tdb_brlock(tdb, TRANSACTION_LOCK, F_WRLCK, F_SETLKW, 0, 1) == -1) {
|
||||
TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: failed to get transaction lock\n"));
|
||||
tdb->ecode = TDB_ERR_LOCK;
|
||||
if (tdb_transaction_lock(tdb, F_WRLCK) == -1) {
|
||||
SAFE_FREE(tdb->transaction);
|
||||
return -1;
|
||||
}
|
||||
@ -468,6 +466,7 @@ int tdb_transaction_start(struct tdb_context *tdb)
|
||||
TDB_HASHTABLE_SIZE(tdb)) != 0) {
|
||||
TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_start: failed to prime hash table\n"));
|
||||
tdb->ecode = TDB_ERR_IO;
|
||||
tdb->methods = tdb->transaction->io_methods;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -475,7 +474,7 @@ int tdb_transaction_start(struct tdb_context *tdb)
|
||||
|
||||
fail:
|
||||
tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 0);
|
||||
tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1);
|
||||
tdb_transaction_unlock(tdb);
|
||||
SAFE_FREE(tdb->transaction->hash_heads);
|
||||
SAFE_FREE(tdb->transaction);
|
||||
return -1;
|
||||
@ -530,7 +529,7 @@ int tdb_transaction_cancel(struct tdb_context *tdb)
|
||||
tdb->methods = tdb->transaction->io_methods;
|
||||
|
||||
tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 0);
|
||||
tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1);
|
||||
tdb_transaction_unlock(tdb);
|
||||
SAFE_FREE(tdb->transaction->hash_heads);
|
||||
SAFE_FREE(tdb->transaction);
|
||||
|
||||
|
@ -204,12 +204,10 @@ int tdb_traverse_read(struct tdb_context *tdb,
|
||||
{
|
||||
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;
|
||||
if (tdb_transaction_lock(tdb, F_RDLCK)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -217,7 +215,7 @@ int tdb_traverse_read(struct tdb_context *tdb,
|
||||
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);
|
||||
tdb_transaction_unlock(tdb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -236,15 +234,13 @@ int tdb_traverse(struct tdb_context *tdb,
|
||||
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;
|
||||
if (tdb_transaction_lock(tdb, F_WRLCK)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = tdb_traverse_internal(tdb, fn, private_data, &tl);
|
||||
|
||||
tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1);
|
||||
tdb_transaction_unlock(tdb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -6,5 +6,9 @@ AC_INIT(tdb, 1.1.0)
|
||||
AC_CONFIG_SRCDIR([common/tdb.c])
|
||||
AC_CONFIG_HEADER(include/config.h)
|
||||
AC_LIBREPLACE_ALL_CHECKS
|
||||
AC_LD_SONAMEFLAG
|
||||
AC_LD_PICFLAG
|
||||
AC_LD_SHLDFLAGS
|
||||
AC_LD_SHLIBEXT
|
||||
m4_include(libtdb.m4)
|
||||
AC_OUTPUT(Makefile tdb.pc)
|
||||
|
@ -116,9 +116,13 @@ int tdb_traverse(struct tdb_context *tdb, tdb_traverse_func fn, void *);
|
||||
int tdb_traverse_read(struct tdb_context *tdb, tdb_traverse_func fn, void *);
|
||||
int tdb_exists(struct tdb_context *tdb, TDB_DATA key);
|
||||
int tdb_lockall(struct tdb_context *tdb);
|
||||
int tdb_lockall_nonblock(struct tdb_context *tdb);
|
||||
int tdb_unlockall(struct tdb_context *tdb);
|
||||
int tdb_lockall_read(struct tdb_context *tdb);
|
||||
int tdb_lockall_read_nonblock(struct tdb_context *tdb);
|
||||
int tdb_unlockall_read(struct tdb_context *tdb);
|
||||
int tdb_lockall_mark(struct tdb_context *tdb);
|
||||
int tdb_lockall_unmark(struct tdb_context *tdb);
|
||||
const char *tdb_name(struct tdb_context *tdb);
|
||||
int tdb_fd(struct tdb_context *tdb);
|
||||
tdb_log_func tdb_log_fn(struct tdb_context *tdb);
|
||||
@ -131,12 +135,17 @@ int tdb_get_seqnum(struct tdb_context *tdb);
|
||||
int tdb_hash_size(struct tdb_context *tdb);
|
||||
size_t tdb_map_size(struct tdb_context *tdb);
|
||||
int tdb_get_flags(struct tdb_context *tdb);
|
||||
void tdb_enable_seqnum(struct tdb_context *tdb);
|
||||
void tdb_increment_seqnum_nonblock(struct tdb_context *tdb);
|
||||
|
||||
/* Low level locking functions: use with care */
|
||||
int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key);
|
||||
int tdb_chainlock_nonblock(struct tdb_context *tdb, TDB_DATA key);
|
||||
int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key);
|
||||
int tdb_chainlock_read(struct tdb_context *tdb, TDB_DATA key);
|
||||
int tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key);
|
||||
int tdb_chainlock_mark(struct tdb_context *tdb, TDB_DATA key);
|
||||
int tdb_chainlock_unmark(struct tdb_context *tdb, TDB_DATA key);
|
||||
|
||||
void tdb_setalarm_sigptr(struct tdb_context *tdb, volatile sig_atomic_t *sigptr);
|
||||
|
||||
|
@ -12,11 +12,17 @@ done
|
||||
if test x"$tdbdir" = "x"; then
|
||||
AC_MSG_ERROR([cannot find tdb source in $tdbpaths])
|
||||
fi
|
||||
TDBOBJ="common/tdb.o common/dump.o common/transaction.o common/error.o common/traverse.o"
|
||||
TDBOBJ="$TDBOBJ common/freelist.o common/freelistcheck.o common/io.o common/lock.o common/open.o"
|
||||
AC_SUBST(TDBOBJ)
|
||||
TDB_OBJ="common/tdb.o common/dump.o common/transaction.o common/error.o common/traverse.o"
|
||||
TDB_OBJ="$TDB_OBJ common/freelist.o common/freelistcheck.o common/io.o common/lock.o common/open.o"
|
||||
AC_SUBST(TDB_OBJ)
|
||||
AC_SUBST(LIBREPLACEOBJ)
|
||||
|
||||
TDB_LIBS=""
|
||||
AC_SUBST(TDB_LIBS)
|
||||
|
||||
TDB_CFLAGS="-I$tdbdir/include"
|
||||
AC_SUBST(TDB_CFLAGS)
|
||||
|
||||
AC_CHECK_FUNCS(mmap pread pwrite getpagesize utime)
|
||||
AC_CHECK_HEADERS(getopt.h sys/select.h sys/time.h)
|
||||
|
||||
|
@ -5,6 +5,6 @@ includedir=@includedir@
|
||||
|
||||
Name: tdb
|
||||
Description: A trivial database
|
||||
Version: 4.0
|
||||
Version: @PACKAGE_VERSION@
|
||||
Libs: -L${libdir} -ltdb
|
||||
Cflags: -I${includedir}
|
||||
|
@ -214,7 +214,7 @@ static void merge_test(void)
|
||||
key.dptr = keys[3];
|
||||
tdb_delete(db, key);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
int i, seed=0;
|
||||
|
@ -238,7 +238,7 @@ static void usage(void)
|
||||
|
||||
unlink("torture.tdb");
|
||||
|
||||
pids = calloc(sizeof(pid_t), num_procs);
|
||||
pids = (pid_t *)calloc(sizeof(pid_t), num_procs);
|
||||
pids[0] = getpid();
|
||||
|
||||
for (i=0;i<num_procs-1;i++) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user