From 99fbf5c4bc870119a12e9b6467beb6a8b8650cc0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 May 2000 00:41:47 +0000 Subject: 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) --- source3/locking/posix.c | 6 +-- source3/tdb/Makefile | 8 ++-- source3/tdb/README | 4 ++ source3/tdb/tdb.c | 103 +++++++++++++++++++++++++++++------------------- source3/tdb/tdb.h | 4 ++ source3/tdb/tdbtest.c | 2 +- 6 files changed, 79 insertions(+), 48 deletions(-) (limited to 'source3') diff --git a/source3/locking/posix.c b/source3/locking/posix.c index 7b4075d5d8..d6eaad89c1 100644 --- a/source3/locking/posix.c +++ b/source3/locking/posix.c @@ -1088,14 +1088,14 @@ BOOL posix_locking_init(void) return True; if (!posix_lock_tdb) - posix_lock_tdb = tdb_open(NULL, 0, TDB_CLEAR_IF_FIRST, - O_RDWR|O_CREAT, 0644); + posix_lock_tdb = tdb_open(NULL, 0, TDB_INTERNAL, + O_RDWR|O_CREAT, 0644); if (!posix_lock_tdb) { DEBUG(0,("Failed to open POSIX byte range locking database.\n")); return False; } if (!posix_pending_close_tdb) - posix_pending_close_tdb = tdb_open(NULL, 0, TDB_CLEAR_IF_FIRST, + posix_pending_close_tdb = tdb_open(NULL, 0, TDB_INTERNAL, O_RDWR|O_CREAT, 0644); if (!posix_pending_close_tdb) { DEBUG(0,("Failed to open POSIX pending close database.\n")); 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); -- cgit