1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-01 04:58:35 +03:00

Changed to sourceforge tdb code. This includes spinlocks (so we now have

a --with-spinlocks option to configure, this does mean the on-disk tdb
format has changed, so 2.2alphaX sites will need to re-create their
tdb's. The upside is no more tdb fragmentation and a +5% on netbench.
Swings and roundabouts....
Jeremy.
(This used to be commit 9dea7b7c257db487f8ced7dad3fce92fba03ea91)
This commit is contained in:
Jeremy Allison 2000-12-06 00:05:15 +00:00
parent 1cd8538b7a
commit 7e4c4721b4
16 changed files with 2334 additions and 2047 deletions

View File

@ -95,7 +95,7 @@ QUOTAOBJS=@QUOTAOBJS@
# object file lists
######################################################################
TDB_OBJ = tdb/tdb.o tdb/tdbutil.o
TDB_OBJ = tdb/tdb.o tdb/spinlock.o tdb/tdbutil.o
LIB_OBJ = lib/charcnv.o lib/charset.o lib/debug.o lib/fault.o \
lib/getsmbpass.o lib/interface.o lib/kanji.o lib/md4.o \

View File

@ -132,3 +132,8 @@
#undef PUTUTLINE_RETURNS_UTMP
#undef COMPILER_SUPPORTS_LL
#undef HAVE_YP_GET_DEFAULT_DOMAIN
#undef USE_SPINLOCKS
#undef SPARC_SPINLOCKS
#undef INTEL_SPINLOCKS
#undef MIPS_SPINLOCKS
#undef POWERPC_SPINLOCKS

1345
source3/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -1902,6 +1902,29 @@ else
echo "no"
fi
AC_ARG_WITH(spinlocks, [ --with-spinlocks use spin locks instead of fcntl locks ])
if test "x$with_spinlocks" = "xyes"; then
AC_DEFINE(USE_SPINLOCKS)
case "$host_cpu" in
sparc)
AC_DEFINE(SPARC_SPINLOCKS)
;;
i386|i486|i586|i686)
AC_DEFINE(INTEL_SPINLOCKS)
;;
mips)
AC_DEFINE(MIPS_SPINLOCKS)
;;
powerpc)
AC_DEFINE(POWERPC_SPINLOCKS)
;;
esac
fi
echo "checking configure summary"
AC_TRY_RUN([#include "${srcdir-.}/tests/summary.c"],
echo "configure OK";,

View File

@ -195,6 +195,11 @@
#undef PUTUTLINE_RETURNS_UTMP
#undef COMPILER_SUPPORTS_LL
#undef HAVE_YP_GET_DEFAULT_DOMAIN
#undef USE_SPINLOCKS
#undef SPARC_SPINLOCKS
#undef INTEL_SPINLOCKS
#undef MIPS_SPINLOCKS
#undef POWERPC_SPINLOCKS
/* The number of bytes in a int. */
#undef SIZEOF_INT

View File

@ -606,6 +606,7 @@ extern int errno;
#include "ubi_dLinkList.h"
#include "dlinklist.h"
#include "../tdb/tdb.h"
#include "../tdb/spinlock.h"
#include "talloc.h"
#include "interfaces.h"
#include "hash.h"

View File

@ -4006,23 +4006,34 @@ int smbw_stat_printjob(struct smbw_server *srv,char *path,
int smbw_fstat(int fd, struct stat *st);
int smbw_stat(const char *fname, struct stat *st);
/*The following definitions come from tdb/spinlock.c */
int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type);
int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type);
int tdb_create_rwlocks(int fd, unsigned int hash_size);
int tdb_clear_spinlocks(TDB_CONTEXT *tdb);
int tdb_clear_spinlocks(TDB_CONTEXT *tdb);
/*The following definitions come from tdb/tdb.c */
char *tdb_error(TDB_CONTEXT *tdb);
int tdb_update(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf);
void tdb_printfreelist(TDB_CONTEXT *tdb);
const char *tdb_errorstr(TDB_CONTEXT *tdb);
TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key);
int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key);
int tdb_traverse(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void* state), void* state);
int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *state);
TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb);
TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key);
TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA oldkey);
int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key);
int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag);
TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
int open_flags, mode_t mode);
int tdb_close(TDB_CONTEXT *tdb);
int tdb_lockchain(TDB_CONTEXT *tdb, TDB_DATA key);
int tdb_unlockchain(TDB_CONTEXT *tdb, TDB_DATA key);
void tdb_printfreelist(TDB_CONTEXT *tdb);
int tdb_lockall(TDB_CONTEXT *tdb);
void tdb_unlockall(TDB_CONTEXT *tdb);
int tdb_lockkeys(TDB_CONTEXT *tdb, u32 number, TDB_DATA keys[]);
void tdb_unlockkeys(TDB_CONTEXT *tdb);
int tdb_chainlock(TDB_CONTEXT *tdb, TDB_DATA key);
void tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key);
/*The following definitions come from tdb/tdbutil.c */

View File

@ -174,7 +174,7 @@ BOOL message_send_pid(pid_t pid, int msg_type, void *buf, size_t len, BOOL dupli
kbuf = message_key_pid(pid);
/* lock the record for the destination */
tdb_lockchain(tdb, kbuf);
tdb_chainlock(tdb, kbuf);
dbuf = tdb_fetch(tdb, kbuf);
@ -208,7 +208,7 @@ BOOL message_send_pid(pid_t pid, int msg_type, void *buf, size_t len, BOOL dupli
if (!len || (len && !memcmp( ptr + sizeof(rec), (char *)buf, len))) {
DEBUG(10,("message_send_pid: discarding duplicate message.\n"));
free(dbuf.dptr);
tdb_unlockchain(tdb, kbuf);
tdb_chainunlock(tdb, kbuf);
return True;
}
}
@ -232,11 +232,11 @@ BOOL message_send_pid(pid_t pid, int msg_type, void *buf, size_t len, BOOL dupli
free(dbuf.dptr);
ok:
tdb_unlockchain(tdb, kbuf);
tdb_chainunlock(tdb, kbuf);
return message_notify(pid);
failed:
tdb_unlockchain(tdb, kbuf);
tdb_chainunlock(tdb, kbuf);
return False;
}
@ -253,7 +253,7 @@ static BOOL message_recv(int *msg_type, pid_t *src, void **buf, size_t *len)
kbuf = message_key_pid(sys_getpid());
tdb_lockchain(tdb, kbuf);
tdb_chainlock(tdb, kbuf);
dbuf = tdb_fetch(tdb, kbuf);
if (dbuf.dptr == NULL || dbuf.dsize == 0) goto failed;
@ -288,11 +288,11 @@ static BOOL message_recv(int *msg_type, pid_t *src, void **buf, size_t *len)
tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
free(dbuf.dptr);
tdb_unlockchain(tdb, kbuf);
tdb_chainunlock(tdb, kbuf);
return True;
failed:
tdb_unlockchain(tdb, kbuf);
tdb_chainunlock(tdb, kbuf);
return False;
}

View File

@ -121,7 +121,7 @@ static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *stat
struct lock_key *key;
int count, i;
tdb_lockchain(tdb, kbuf);
tdb_chainlock(tdb, kbuf);
locks = (struct lock_struct *)dbuf.dptr;
key = (struct lock_key *)kbuf.dptr;
@ -147,7 +147,7 @@ static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *stat
tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
}
tdb_unlockchain(tdb, kbuf);
tdb_chainunlock(tdb, kbuf);
return 0;
}
@ -188,7 +188,7 @@ BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
dbuf.dptr = NULL;
tdb_lockchain(tdb, kbuf);
tdb_chainlock(tdb, kbuf);
dbuf = tdb_fetch(tdb, kbuf);
lock.context.smbpid = smbpid;
@ -218,12 +218,12 @@ BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
free(dbuf.dptr);
tdb_unlockchain(tdb, kbuf);
tdb_chainunlock(tdb, kbuf);
return True;
fail:
if (dbuf.dptr) free(dbuf.dptr);
tdb_unlockchain(tdb, kbuf);
tdb_chainunlock(tdb, kbuf);
return False;
}
@ -244,7 +244,7 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
dbuf.dptr = NULL;
tdb_lockchain(tdb, kbuf);
tdb_chainlock(tdb, kbuf);
dbuf = tdb_fetch(tdb, kbuf);
if (!dbuf.dptr) {
@ -292,7 +292,7 @@ smbpid = %u, pid = %u, tid = %u\n",
}
free(dbuf.dptr);
tdb_unlockchain(tdb, kbuf);
tdb_chainunlock(tdb, kbuf);
return True;
}
}
@ -301,7 +301,7 @@ smbpid = %u, pid = %u, tid = %u\n",
fail:
if (dbuf.dptr) free(dbuf.dptr);
tdb_unlockchain(tdb, kbuf);
tdb_chainunlock(tdb, kbuf);
return False;
}
@ -322,7 +322,7 @@ BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
dbuf.dptr = NULL;
tdb_lockchain(tdb, kbuf);
tdb_chainlock(tdb, kbuf);
dbuf = tdb_fetch(tdb, kbuf);
lock.context.smbpid = smbpid;
@ -346,12 +346,12 @@ BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
/* no conflicts - we could have added it */
free(dbuf.dptr);
tdb_unlockchain(tdb, kbuf);
tdb_chainunlock(tdb, kbuf);
return True;
fail:
if (dbuf.dptr) free(dbuf.dptr);
tdb_unlockchain(tdb, kbuf);
tdb_chainunlock(tdb, kbuf);
return False;
}
@ -369,7 +369,7 @@ void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum)
dbuf.dptr = NULL;
tdb_lockchain(tdb, kbuf);
tdb_chainlock(tdb, kbuf);
dbuf = tdb_fetch(tdb, kbuf);
if (!dbuf.dptr) goto fail;
@ -404,7 +404,7 @@ void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum)
/* we didn't find it */
fail:
if (dbuf.dptr) free(dbuf.dptr);
tdb_unlockchain(tdb, kbuf);
tdb_chainunlock(tdb, kbuf);
}
/****************************************************************************

View File

@ -274,7 +274,7 @@ static TDB_DATA locking_key_fsp(files_struct *fsp)
BOOL lock_share_entry(connection_struct *conn,
SMB_DEV_T dev, SMB_INO_T inode)
{
return tdb_lockchain(tdb, locking_key(dev, inode)) == 0;
return tdb_chainlock(tdb, locking_key(dev, inode)) == 0;
}
/*******************************************************************
@ -283,7 +283,7 @@ BOOL lock_share_entry(connection_struct *conn,
BOOL unlock_share_entry(connection_struct *conn,
SMB_DEV_T dev, SMB_INO_T inode)
{
return tdb_unlockchain(tdb, locking_key(dev, inode)) == 0;
return tdb_chainunlock(tdb, locking_key(dev, inode)) == 0;
}
@ -292,7 +292,7 @@ BOOL unlock_share_entry(connection_struct *conn,
******************************************************************/
BOOL lock_share_entry_fsp(files_struct *fsp)
{
return tdb_lockchain(tdb, locking_key(fsp->dev, fsp->inode)) == 0;
return tdb_chainlock(tdb, locking_key(fsp->dev, fsp->inode)) == 0;
}
/*******************************************************************
@ -300,7 +300,7 @@ BOOL lock_share_entry_fsp(files_struct *fsp)
******************************************************************/
BOOL unlock_share_entry_fsp(files_struct *fsp)
{
return tdb_unlockchain(tdb, locking_key(fsp->dev, fsp->inode)) == 0;
return tdb_chainunlock(tdb, locking_key(fsp->dev, fsp->inode)) == 0;
}
/*******************************************************************

View File

@ -8,14 +8,14 @@ PROGS = tdbtest tdbtool tdbtorture
default: $(PROGS)
tdbtest: tdbtest.o tdb.o
$(CC) $(CFLAGS) -o tdbtest tdbtest.o tdb.o -lgdbm
tdbtest: tdbtest.o tdb.o spinlock.o
$(CC) $(CFLAGS) -o tdbtest tdbtest.o tdb.o spinlock.o -lgdbm
tdbtool: tdbtool.o tdb.o
$(CC) $(CFLAGS) -o tdbtool tdbtool.o tdb.o
tdbtool: tdbtool.o tdb.o spinlock.o
$(CC) $(CFLAGS) -o tdbtool tdbtool.o tdb.o spinlock.o
tdbtorture: tdbtorture.o tdb.o
$(CC) $(CFLAGS) -o tdbtorture tdbtorture.o tdb.o
$(CC) $(CFLAGS) -o tdbtorture tdbtorture.o tdb.o spinlock.o
clean:
rm -f $(PROGS) *.o *~ *% core test.db test.tdb test.gdbm

403
source3/tdb/spinlock.c Normal file
View File

@ -0,0 +1,403 @@
#if STANDALONE
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/stat.h>
#include <time.h>
#include "tdb.h"
#include "spinlock.h"
#define DEBUG
#else
#include "includes.h"
#endif
#ifdef USE_SPINLOCKS
/*
* ARCH SPECIFIC
*/
#if defined(SPARC_SPINLOCKS)
static inline int __spin_trylock(spinlock_t *lock)
{
unsigned int result;
asm volatile("ldstub [%1], %0"
: "=r" (result)
: "r" (lock)
: "memory");
return (result == 0) ? 0 : EBUSY;
}
static inline void __spin_unlock(spinlock_t *lock)
{
*lock = 0;
}
static inline void __spin_lock_init(spinlock_t *lock)
{
*lock = 0;
}
static inline int __spin_is_locked(spinlock_t *lock)
{
return (*lock != 0);
}
#elif defined(POWERPC_SPINLOCKS)
static inline int __spin_trylock(spinlock_t *lock)
{
int result;
__asm__ __volatile__ (
" eieio;"
"0: lwarx %0,0,%1;"
" cmpwi 0,%0,0;"
" bne- 1f;"
" stwcx. %2,0,%1;"
" bne- 0b;"
" sync;"
"1:"
: "=&r"(result)
: "r"(lock), "r"(1)
: "cr0", "memory");
return (result == 0) ? 0 : EBUSY;
}
static inline void __spin_unlock(spinlock_t *lock)
{
asm volatile("sync");
*lock = 0;
}
static inline void __spin_lock_init(spinlock_t *lock)
{
*lock = 0;
}
static inline int __spin_is_locked(spinlock_t *lock)
{
return (*lock != 0);
}
#elif defined(INTEL_SPINLOCKS)
static inline int __spin_trylock(spinlock_t *lock)
{
int oldval;
asm volatile("xchgl %0,%1"
: "=r" (oldval), "=m" (*lock)
: "0" (0));
return oldval > 0 ? 0 : EBUSY;
}
static inline void __spin_unlock(spinlock_t *lock)
{
*lock = 1;
}
static inline void __spin_lock_init(spinlock_t *lock)
{
*lock = 1;
}
static inline int __spin_is_locked(spinlock_t *lock)
{
return (*lock != 1);
}
#elif defined(MIPS_SPINLOCKS)
static inline unsigned int load_linked(unsigned long addr)
{
unsigned int res;
__asm__ __volatile__("ll\t%0,(%1)"
: "=r" (res)
: "r" (addr));
return res;
}
static inline unsigned int store_conditional(unsigned long addr, unsigned int value)
{
unsigned int res;
__asm__ __volatile__("sc\t%0,(%2)"
: "=r" (res)
: "0" (value), "r" (addr));
return res;
}
static inline int __spin_trylock(spinlock_t *lock)
{
unsigned int mw;
do {
mw = load_linked(lock);
if (mw)
return EBUSY;
} while (!store_conditional(lock, 1));
return 0;
}
static inline void __spin_unlock(spinlock_t *lock)
{
*lock = 0;
}
static inline void __spin_lock_init(spinlock_t *lock)
{
*lock = 0;
}
static inline int __spin_is_locked(spinlock_t *lock)
{
return (*lock != 0);
}
#else
#error Need to implement spinlock code in spinlock.c
#endif
/*
* OS SPECIFIC
*/
static void yield_cpu(void)
{
struct timespec tm;
#ifdef USE_SCHED_YIELD
sched_yield();
#else
/* Linux will busy loop for delays < 2ms on real time tasks */
tm.tv_sec = 0;
tm.tv_nsec = 2000000L + 1;
nanosleep(&tm, NULL);
#endif
}
static int this_is_smp(void)
{
return 0;
}
/*
* GENERIC
*/
static int smp_machine = 0;
static inline void __spin_lock(spinlock_t *lock)
{
int ntries = 0;
while(__spin_trylock(lock)) {
while(__spin_is_locked(lock)) {
if (smp_machine && ntries++ < MAX_BUSY_LOOPS)
continue;
yield_cpu();
}
}
}
static void __read_lock(rwlock_t *rwlock)
{
int ntries = 0;
while(1) {
__spin_lock(&rwlock->lock);
if (!(rwlock->count & RWLOCK_BIAS)) {
rwlock->count++;
__spin_unlock(&rwlock->lock);
return;
}
__spin_unlock(&rwlock->lock);
while(rwlock->count & RWLOCK_BIAS) {
if (smp_machine && ntries++ < MAX_BUSY_LOOPS)
continue;
yield_cpu();
}
}
}
static void __write_lock(rwlock_t *rwlock)
{
int ntries = 0;
while(1) {
__spin_lock(&rwlock->lock);
if (rwlock->count == 0) {
rwlock->count |= RWLOCK_BIAS;
__spin_unlock(&rwlock->lock);
return;
}
__spin_unlock(&rwlock->lock);
while(rwlock->count != 0) {
if (smp_machine && ntries++ < MAX_BUSY_LOOPS)
continue;
yield_cpu();
}
}
}
static void __write_unlock(rwlock_t *rwlock)
{
__spin_lock(&rwlock->lock);
#ifdef DEBUG
if (!(rwlock->count & RWLOCK_BIAS))
fprintf(stderr, "bug: write_unlock\n");
#endif
rwlock->count &= ~RWLOCK_BIAS;
__spin_unlock(&rwlock->lock);
}
static void __read_unlock(rwlock_t *rwlock)
{
__spin_lock(&rwlock->lock);
#ifdef DEBUG
if (!rwlock->count)
fprintf(stderr, "bug: read_unlock\n");
if (rwlock->count & RWLOCK_BIAS)
fprintf(stderr, "bug: read_unlock\n");
#endif
rwlock->count--;
__spin_unlock(&rwlock->lock);
}
/* TDB SPECIFIC */
/* lock a list in the database. list -1 is the alloc list */
int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type)
{
rwlock_t *rwlocks;
if (!tdb->map_ptr) return -1;
rwlocks = (rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks);
switch(rw_type) {
case F_RDLCK:
__read_lock(&rwlocks[list+1]);
break;
case F_WRLCK:
__write_lock(&rwlocks[list+1]);
break;
default:
return TDB_ERRCODE(TDB_ERR_LOCK, -1);
}
return 0;
}
/* unlock the database. */
int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type)
{
rwlock_t *rwlocks;
if (!tdb->map_ptr) return -1;
rwlocks = (rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks);
switch(rw_type) {
case F_RDLCK:
__read_unlock(&rwlocks[list+1]);
break;
case F_WRLCK:
__write_unlock(&rwlocks[list+1]);
break;
default:
return TDB_ERRCODE(TDB_ERR_LOCK, -1);
}
return 0;
}
int tdb_create_rwlocks(int fd, unsigned int hash_size)
{
unsigned size, i;
rwlock_t *rwlocks;
size = (hash_size + 1) * sizeof(rwlock_t);
rwlocks = malloc(size);
if (!rwlocks)
return -1;
for(i = 0; i < hash_size+1; i++) {
__spin_lock_init(&rwlocks[i].lock);
rwlocks[i].count = 0;
}
/* Write it out (appending to end) */
if (write(fd, rwlocks, size) != size) {
free(rwlocks);
return -1;
}
smp_machine = this_is_smp();
free(rwlocks);
return 0;
}
int tdb_clear_spinlocks(TDB_CONTEXT *tdb)
{
rwlock_t *rwlocks;
unsigned i;
if (tdb->header.rwlocks == 0) return 0;
if (!tdb->map_ptr) return -1;
/* We're mmapped here */
rwlocks = (rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks);
for(i = 0; i < tdb->header.hash_size+1; i++) {
__spin_lock_init(&rwlocks[i].lock);
rwlocks[i].count = 0;
}
return 0;
}
#else
int tdb_create_rwlocks(int fd, unsigned int hash_size) { return 0; }
int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type) { return -1; }
int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type) { return -1; }
/* Non-spinlock version: remove spinlock pointer */
int tdb_clear_spinlocks(TDB_CONTEXT *tdb)
{
tdb_off off = (tdb_off)((char *)&tdb->header.rwlocks
- (char *)&tdb->header);
tdb->header.rwlocks = 0;
if (lseek(tdb->fd, off, SEEK_SET) != off
|| write(tdb->fd, (void *)&tdb->header.rwlocks,
sizeof(tdb->header.rwlocks))
!= sizeof(tdb->header.rwlocks))
return -1;
return 0;
}
#endif

55
source3/tdb/spinlock.h Normal file
View File

@ -0,0 +1,55 @@
#ifndef __SPINLOCK_H__
#define __SPINLOCK_H__
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include "tdb.h"
#ifdef USE_SPINLOCKS
#define RWLOCK_BIAS 0x1000UL
/* OS SPECIFIC */
#define MAX_BUSY_LOOPS 1000
#undef USE_SCHED_YIELD
/* ARCH SPECIFIC */
/* We should make sure these are padded to a cache line */
#if defined(SPARC_SPINLOCKS)
typedef volatile char spinlock_t;
#elif defined(POWERPC_SPINLOCKS)
typedef volatile unsigned long spinlock_t;
#elif defined(INTEL_SPINLOCKS)
typedef volatile int spinlock_t;
#elif defined(MIPS_SPINLOCKS)
typedef volatile unsigned long spinlock_t;
#else
#error Need to implement spinlock code in spinlock.h
#endif
typedef struct {
spinlock_t lock;
volatile int count;
} rwlock_t;
int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type);
int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type);
int tdb_create_rwlocks(int fd, unsigned int hash_size);
int tdb_clear_spinlocks(TDB_CONTEXT *tdb);
#else /* !USE_SPINLOCKS */
#if 0
#define tdb_create_rwlocks(fd, hash_size) 0
#define tdb_spinlock(tdb, list, rw_type) (-1)
#define tdb_spinunlock(tdb, list, rw_type) (-1)
#else
int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type);
int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type);
int tdb_create_rwlocks(int fd, unsigned int hash_size);
#endif
int tdb_clear_spinlocks(TDB_CONTEXT *tdb);
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,6 @@
#ifndef __TDB_H__
#define __TDB_H__
/*
Unix SMB/Netbios implementation.
Version 3.0
@ -19,41 +22,10 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
typedef unsigned tdb_len;
typedef unsigned tdb_off;
#ifdef __cplusplus
extern "C" {
#endif
#define TDB_MAGIC_FOOD "TDB file\n"
/* this is stored at the front of every database */
struct tdb_header {
char magic_food[32]; /* for /etc/magic */
unsigned version; /* version of the code */
unsigned hash_size; /* number of hash entries */
tdb_off reserved[32];
};
typedef struct {
char *dptr;
size_t dsize;
} TDB_DATA;
struct tdb_lock_type {
unsigned count;
unsigned ltype;
};
/* this is the context structure that is returned from a db open */
typedef struct {
char *name; /* the name of the database */
void *map_ptr; /* where it is currently mapped */
int fd; /* open file descriptor for the database */
tdb_len map_size; /* how much space has been mapped */
int read_only; /* opened read-only */
struct tdb_lock_type *locked; /* set if we have a chain locked */
int ecode; /* error code for last tdb error */
struct tdb_header header; /* a cached copy of the header */
unsigned flags; /* the flags passed to tdb_open */
} TDB_CONTEXT;
/* flags to tdb_store() */
#define TDB_REPLACE 1
@ -61,31 +33,94 @@ typedef struct {
#define TDB_MODIFY 3
/* flags for tdb_open() */
#define TDB_DEFAULT 0 /* just a readability place holder */
#define TDB_CLEAR_IF_FIRST 1
#define TDB_INTERNAL 2 /* don't store on disk */
#define TDB_NOLOCK 4 /* don't do any locking */
#define TDB_NOMMAP 8 /* don't use mmap */
#define TDB_CONVERT 16 /* convert endian (internal use) */
#define TDB_ERRCODE(code, ret) ((tdb->ecode = (code)), ret)
/* error codes */
enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK,
TDB_ERR_OOM, TDB_ERR_EXISTS, TDB_ERR_NOEXIST };
TDB_ERR_OOM, TDB_ERR_EXISTS, TDB_ERR_NOEXIST, TDB_ERR_NOLOCK };
#ifndef u32
#define u32 unsigned
#endif
typedef struct {
char *dptr;
size_t dsize;
} TDB_DATA;
typedef u32 tdb_len;
typedef u32 tdb_off;
/* this is stored at the front of every database */
struct tdb_header {
char magic_food[32]; /* for /etc/magic */
u32 version; /* version of the code */
u32 hash_size; /* number of hash entries */
tdb_off rwlocks;
tdb_off reserved[31];
};
struct tdb_lock_type {
u32 count;
u32 ltype;
};
struct tdb_traverse_lock {
struct tdb_traverse_lock *next;
u32 off;
u32 hash;
};
/* this is the context structure that is returned from a db open */
typedef struct tdb_context {
char *name; /* the name of the database */
void *map_ptr; /* where it is currently mapped */
int fd; /* open file descriptor for the database */
tdb_len map_size; /* how much space has been mapped */
int read_only; /* opened read-only */
struct tdb_lock_type *locked; /* array of chain locks */
enum TDB_ERROR ecode; /* error code for last tdb error */
struct tdb_header header; /* a cached copy of the header */
u32 flags; /* the flags passed to tdb_open */
u32 *lockedkeys; /* array of locked keys: first is #keys */
struct tdb_traverse_lock travlocks; /* current traversal locks */
struct tdb_context *next; /* all tdbs to avoid multiple opens */
dev_t device; /* uniquely identifies this tdb */
ino_t inode; /* uniquely identifies this tdb */
} TDB_CONTEXT;
typedef int (*tdb_traverse_func)(TDB_CONTEXT *, TDB_DATA, TDB_DATA, void *);
#if STANDALONE
TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
int open_flags, mode_t mode);
char *tdb_error(TDB_CONTEXT *tdb);
int tdb_writelock(TDB_CONTEXT *tdb);
int tdb_writeunlock(TDB_CONTEXT *tdb);
enum TDB_ERROR tdb_error(TDB_CONTEXT *tdb);
const char *tdb_errorstr(TDB_CONTEXT *tdb);
TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key);
int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key);
int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag);
int tdb_close(TDB_CONTEXT *tdb);
TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb);
TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key);
int tdb_traverse(TDB_CONTEXT *tdb,
int (*fn)(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state),
void *state);
int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *state);
int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key);
int tdb_lockkeys(TDB_CONTEXT *tdb, u32 number, TDB_DATA keys[]);
void tdb_unlockkeys(TDB_CONTEXT *tdb);
int tdb_lockall(TDB_CONTEXT *tdb);
void tdb_unlockall(TDB_CONTEXT *tdb);
/* Low level locking functions: use with care */
int tdb_chainlock(TDB_CONTEXT *tdb, TDB_DATA key);
void tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key);
extern TDB_DATA tdb_null;
#ifdef __cplusplus
}
#endif
#endif /* tdb.h */

View File

@ -32,7 +32,7 @@ int tdb_lock_bystring(TDB_CONTEXT *tdb, char *keyval)
key.dptr = keyval;
key.dsize = strlen(keyval)+1;
return tdb_lockchain(tdb, key);
return tdb_chainlock(tdb, key);
}
/* unlock a chain by string */
@ -43,7 +43,7 @@ int tdb_unlock_bystring(TDB_CONTEXT *tdb, char *keyval)
key.dptr = keyval;
key.dsize = strlen(keyval)+1;
return tdb_unlockchain(tdb, key);
return tdb_chainunlock(tdb, key);
}
/* lock a chain by string key */