added TDB_INTERNAL, TDB_NOLOCK and TDB_NOMMAP flags.
authorAndrew Tridgell <tridge@samba.org>
Mon, 1 May 2000 00:41:47 +0000 (00:41 +0000)
committerAndrew Tridgell <tridge@samba.org>
Mon, 1 May 2000 00:41:47 +0000 (00:41 +0000)
TDB_INTERNAL replaces the old method of passing a null filename

source/locking/posix.c
source/tdb/Makefile
source/tdb/README
source/tdb/tdb.c
source/tdb/tdb.h
source/tdb/tdbtest.c

index 7b4075d5d8e2c93e94235c6fbd9b1857fe39d528..d6eaad89c14585e190d1c2db39eac7dae069c1e2 100644 (file)
@@ -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"));
index dbc59047c741d1e36759c2c44b99c3abd3fe2d23..e7988c8106aa678c444c27252c0a220fde02dd3a 100644 (file)
@@ -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
index 96fdcf5c994ddf934c620a8f60856f2115f6af1c..fac3eacb4db3c2c1f1353057e16c28eb0d5c9761 100644 (file)
@@ -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);
index a1483d42d21a017466111d14820a051c7013ee03..998630cb84d2c2f4d2478cbfc1b1b82a0a3000a2 100644 (file)
@@ -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));
index 90a1cccfac9512cd82605d9407c3a1b46c9f1a81..f4039f119c1b46eecb36953db4212301a0633790 100644 (file)
@@ -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, 
index 9728e59a0177e08289ed7e9442d1a4861e3d59e2..67580f906799246009bc5a55e0aea0770d8a370e 100644 (file)
@@ -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);