summaryrefslogtreecommitdiff
path: root/source3/tdb
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2000-05-01 00:41:47 +0000
committerAndrew Tridgell <tridge@samba.org>2000-05-01 00:41:47 +0000
commit99fbf5c4bc870119a12e9b6467beb6a8b8650cc0 (patch)
tree3d62f00287252c9af4b13db36c2ed683c7fbe197 /source3/tdb
parent05cb3464f972d336dcb82ca332bf9b2617646070 (diff)
downloadsamba-99fbf5c4bc870119a12e9b6467beb6a8b8650cc0.tar.gz
samba-99fbf5c4bc870119a12e9b6467beb6a8b8650cc0.tar.bz2
samba-99fbf5c4bc870119a12e9b6467beb6a8b8650cc0.zip
added TDB_INTERNAL, TDB_NOLOCK and TDB_NOMMAP flags.
TDB_INTERNAL replaces the old method of passing a null filename (This used to be commit 8ec815920d46f205b9f3fff82397c731753c3a10)
Diffstat (limited to 'source3/tdb')
-rw-r--r--source3/tdb/Makefile8
-rw-r--r--source3/tdb/README4
-rw-r--r--source3/tdb/tdb.c103
-rw-r--r--source3/tdb/tdb.h4
-rw-r--r--source3/tdb/tdbtest.c2
5 files changed, 76 insertions, 45 deletions
diff --git a/source3/tdb/Makefile b/source3/tdb/Makefile
index dbc59047c7..e7988c8106 100644
--- a/source3/tdb/Makefile
+++ b/source3/tdb/Makefile
@@ -3,19 +3,19 @@
#
CFLAGS = -DSTANDALONE -DTDB_DEBUG -g -DMMAP
-CC = gcc
+CC = insure
PROGS = tdbtest tdbtool tdbtorture
default: $(PROGS)
tdbtest: tdbtest.o tdb.o
- gcc -o tdbtest tdbtest.o tdb.o -lgdbm
+ $(CC) $(CFLAGS) -o tdbtest tdbtest.o tdb.o -lgdbm
tdbtool: tdbtool.o tdb.o
- gcc -o tdbtool tdbtool.o tdb.o
+ $(CC) $(CFLAGS) -o tdbtool tdbtool.o tdb.o
tdbtorture: tdbtorture.o tdb.o
- gcc -o tdbtorture tdbtorture.o tdb.o
+ $(CC) $(CFLAGS) -o tdbtorture tdbtorture.o tdb.o
clean:
rm -f $(PROGS) *.o *~ *% core test.db test.tdb test.gdbm
diff --git a/source3/tdb/README b/source3/tdb/README
index 96fdcf5c99..fac3eacb4d 100644
--- a/source3/tdb/README
+++ b/source3/tdb/README
@@ -64,6 +64,10 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
possible tdb_flags are:
TDB_CLEAR_IF_FIRST - clear database if we are the only one with it open
+ TDB_INTERNAL - don't use a file, instaed store the data in
+ memory. The filename is ignored in this case.
+ TDB_NOLOCK - don't do any locking
+ TDB_NOMMAP - don't use mmap
----------------------------------------------------------------------
char *tdb_error(TDB_CONTEXT *tdb);
diff --git a/source3/tdb/tdb.c b/source3/tdb/tdb.c
index a1483d42d2..998630cb84 100644
--- a/source3/tdb/tdb.c
+++ b/source3/tdb/tdb.c
@@ -88,12 +88,9 @@ static TDB_DATA null_data;
static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset,
int set, int rw_type, int lck_type)
{
-#if NOLOCK
- return 0;
-#else
struct flock fl;
- if (tdb->fd == -1) return 0; /* for in memory tdb */
+ if (tdb->flags & TDB_NOLOCK) return 0;
if (tdb->read_only) return -1;
@@ -114,7 +111,6 @@ static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset,
return -1;
}
return 0;
-#endif
}
/* lock a list in the database. list -1 is the alloc list */
@@ -126,6 +122,9 @@ static int tdb_lock(TDB_CONTEXT *tdb, int list)
#endif
return -1;
}
+
+ if (tdb->flags & TDB_NOLOCK) return 0;
+
if (tdb->locked[list+1] == 0) {
if (tdb_brlock(tdb, LIST_LOCK_BASE + 4*list, LOCK_SET,
F_WRLCK, F_SETLKW) != 0) {
@@ -146,6 +145,8 @@ static int tdb_unlock(TDB_CONTEXT *tdb, int list)
return -1;
}
+ if (tdb->flags & TDB_NOLOCK) return 0;
+
if (tdb->locked[list+1] == 0) {
#if TDB_DEBUG
printf("not locked %d\n", list);
@@ -197,7 +198,9 @@ static tdb_off tdb_hash_top(TDB_CONTEXT *tdb, unsigned hash)
static int tdb_oob(TDB_CONTEXT *tdb, tdb_off offset)
{
struct stat st;
- if ((offset <= tdb->map_size) || (tdb->fd == -1)) return 0;
+ if (offset <= tdb->map_size) return 0;
+
+ if (tdb->flags & TDB_INTERNAL) return 0;
fstat(tdb->fd, &st);
if (st.st_size <= (size_t)offset) {
@@ -214,9 +217,11 @@ static int tdb_oob(TDB_CONTEXT *tdb, tdb_off offset)
tdb->map_size = st.st_size;
#if HAVE_MMAP
- tdb->map_ptr = (void *)mmap(NULL, tdb->map_size,
- tdb->read_only?PROT_READ:PROT_READ|PROT_WRITE,
- MAP_SHARED | MAP_FILE, tdb->fd, 0);
+ if (!(tdb->flags & TDB_NOMMAP)) {
+ tdb->map_ptr = (void *)mmap(NULL, tdb->map_size,
+ tdb->read_only?PROT_READ:PROT_READ|PROT_WRITE,
+ MAP_SHARED | MAP_FILE, tdb->fd, 0);
+ }
#endif
return 0;
}
@@ -340,9 +345,9 @@ static int tdb_expand(TDB_CONTEXT *tdb, tdb_off length)
length = ((tdb->map_size + length + TDB_PAGE_SIZE) & ~(TDB_PAGE_SIZE - 1)) - tdb->map_size;
/* expand the file itself */
- if (tdb->fd != -1) {
- lseek(tdb->fd, tdb->map_size + length - 1, SEEK_SET);
- if (write(tdb->fd, &b, 1) != 1) goto fail;
+ if (!(tdb->flags & TDB_INTERNAL)) {
+ lseek(tdb->fd, tdb->map_size + length - 1, SEEK_SET);
+ if (write(tdb->fd, &b, 1) != 1) goto fail;
}
/* form a new freelist record */
@@ -354,7 +359,7 @@ static int tdb_expand(TDB_CONTEXT *tdb, tdb_off length)
}
#if HAVE_MMAP
- if (tdb->fd != -1 && tdb->map_ptr) {
+ if (!(tdb->flags & TDB_INTERNAL) && tdb->map_ptr) {
munmap(tdb->map_ptr, tdb->map_size);
tdb->map_ptr = NULL;
}
@@ -362,8 +367,8 @@ static int tdb_expand(TDB_CONTEXT *tdb, tdb_off length)
tdb->map_size += length;
- if (tdb->fd == -1) {
- tdb->map_ptr = realloc(tdb->map_ptr, tdb->map_size);
+ if (tdb->flags & TDB_INTERNAL) {
+ tdb->map_ptr = realloc(tdb->map_ptr, tdb->map_size);
}
/* write it out */
@@ -376,10 +381,10 @@ static int tdb_expand(TDB_CONTEXT *tdb, tdb_off length)
if (ofs_write(tdb, offset, &ptr) == -1) goto fail;
#if HAVE_MMAP
- if (tdb->fd != -1) {
- tdb->map_ptr = (void *)mmap(NULL, tdb->map_size,
- PROT_READ|PROT_WRITE,
- MAP_SHARED | MAP_FILE, tdb->fd, 0);
+ if (!(tdb->flags & TDB_NOMMAP)) {
+ tdb->map_ptr = (void *)mmap(NULL, tdb->map_size,
+ PROT_READ|PROT_WRITE,
+ MAP_SHARED | MAP_FILE, tdb->fd, 0);
}
#endif
@@ -498,8 +503,10 @@ static int tdb_new_database(TDB_CONTEXT *tdb, int hash_size)
memcpy(header.magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1);
header.version = TDB_VERSION;
header.hash_size = hash_size;
- lseek(tdb->fd, 0, SEEK_SET);
- if (tdb->fd != -1) ftruncate(tdb->fd, 0);
+ if (tdb->fd != -1) {
+ lseek(tdb->fd, 0, SEEK_SET);
+ ftruncate(tdb->fd, 0);
+ }
if (tdb->fd != -1 && write(tdb->fd, &header, sizeof(header)) !=
sizeof(header)) {
@@ -527,14 +534,14 @@ static int tdb_new_database(TDB_CONTEXT *tdb, int hash_size)
} else size += sizeof(tdb_off);
}
- if (tdb->fd == -1) {
- tdb->map_ptr = calloc(size, 1);
- tdb->map_size = size;
- if (tdb->map_ptr == NULL) {
- tdb->ecode = TDB_ERR_IO;
- return -1;
- }
- memcpy(&tdb->header, &header, sizeof(header));
+ if (tdb->flags & TDB_INTERNAL) {
+ tdb->map_ptr = calloc(size,1);
+ tdb->map_size = size;
+ if (tdb->map_ptr == NULL) {
+ tdb->ecode = TDB_ERR_IO;
+ return -1;
+ }
+ memcpy(&tdb->header, &header, sizeof(header));
}
#if TDB_DEBUG
@@ -1141,6 +1148,7 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
tdb.fd = -1;
tdb.name = NULL;
tdb.map_ptr = NULL;
+ tdb.flags = tdb_flags;
if ((open_flags & O_ACCMODE) == O_WRONLY) {
goto fail;
@@ -1150,7 +1158,20 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
tdb.read_only = ((open_flags & O_ACCMODE) == O_RDONLY);
- if (name == NULL) goto in_memory;
+ /* internal databases don't use mmap or locking,
+ and start off cleared */
+ if (tdb.flags & TDB_INTERNAL) {
+ tdb.flags |= (TDB_NOLOCK | TDB_NOMMAP);
+ tdb.flags &= ~TDB_CLEAR_IF_FIRST;
+ }
+
+ /* read only databases don't do locking */
+ if (tdb.read_only) tdb.flags |= TDB_NOLOCK;
+
+ if (tdb.flags & TDB_INTERNAL) {
+ tdb_new_database(&tdb, hash_size);
+ goto internal;
+ }
tdb.fd = open(name, open_flags, mode);
if (tdb.fd == -1) {
@@ -1195,16 +1216,18 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
tdb.locked = (int *)calloc(tdb.header.hash_size+1,
sizeof(tdb.locked[0]));
if (!tdb.locked) {
- goto fail;
+ goto fail;
}
#if HAVE_MMAP
- tdb.map_ptr = (void *)mmap(NULL, st.st_size,
- tdb.read_only? PROT_READ : PROT_READ|PROT_WRITE,
- MAP_SHARED | MAP_FILE, tdb.fd, 0);
+ if (!(tdb->flags & TDB_NOMMAP)) {
+ tdb.map_ptr = (void *)mmap(NULL, st.st_size,
+ tdb.read_only? PROT_READ : PROT_READ|PROT_WRITE,
+ MAP_SHARED | MAP_FILE, tdb.fd, 0);
+ }
#endif
- in_memory:
+ internal:
ret = (TDB_CONTEXT *)malloc(sizeof(tdb));
if (!ret) goto fail;
@@ -1236,11 +1259,11 @@ int tdb_close(TDB_CONTEXT *tdb)
if (tdb->locked) free(tdb->locked);
if (tdb->map_ptr) {
- if (tdb->fd != -1) {
- munmap(tdb->map_ptr, tdb->map_size);
- } else {
- free(tdb->map_ptr);
- }
+ if (tdb->flags & TDB_INTERNAL) {
+ free(tdb->map_ptr);
+ } else {
+ munmap(tdb->map_ptr, tdb->map_size);
+ }
}
memset(tdb, 0, sizeof(*tdb));
diff --git a/source3/tdb/tdb.h b/source3/tdb/tdb.h
index 90a1cccfac..f4039f119c 100644
--- a/source3/tdb/tdb.h
+++ b/source3/tdb/tdb.h
@@ -46,6 +46,7 @@ typedef struct {
int *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() */
@@ -55,6 +56,9 @@ typedef struct {
/* flags for tdb_open() */
#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 */
/* error codes */
enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK,
diff --git a/source3/tdb/tdbtest.c b/source3/tdb/tdbtest.c
index 9728e59a01..67580f9067 100644
--- a/source3/tdb/tdbtest.c
+++ b/source3/tdb/tdbtest.c
@@ -184,7 +184,7 @@ int main(int argc, char *argv[])
unlink("test.gdbm");
- db = tdb_open("test.db", 0, TDB_CLEAR_IF_FIRST,
+ db = tdb_open("test.tdb", 0, TDB_CLEAR_IF_FIRST,
O_RDWR | O_CREAT | O_TRUNC, 0600);
gdbm = gdbm_open("test.gdbm", 512, GDBM_WRITER|GDBM_NEWDB|GDBM_FAST,
0600, NULL);