]> git.ozlabs.org Git - ccan/blobdiff - ccan/tdb2/tdb1_tdb.c
tdb2: unify tdb1_parse_record into tdb_parse_record
[ccan] / ccan / tdb2 / tdb1_tdb.c
index 8392e71240f33c70e1747d62b06ad9ba71df4c52..a50303c33ce4e6333e823ceea2cceff6788e60f7 100644 (file)
@@ -26,6 +26,7 @@
 */
 
 #include "tdb1_private.h"
 */
 
 #include "tdb1_private.h"
+#include <assert.h>
 
 TDB_DATA tdb1_null;
 
 
 TDB_DATA tdb1_null;
 
@@ -33,7 +34,7 @@ TDB_DATA tdb1_null;
   non-blocking increment of the tdb sequence number if the tdb has been opened using
   the TDB_SEQNUM flag
 */
   non-blocking increment of the tdb sequence number if the tdb has been opened using
   the TDB_SEQNUM flag
 */
-void tdb1_increment_seqnum_nonblock(struct tdb1_context *tdb)
+void tdb1_increment_seqnum_nonblock(struct tdb_context *tdb)
 {
        tdb1_off_t seqnum=0;
 
 {
        tdb1_off_t seqnum=0;
 
@@ -53,7 +54,7 @@ void tdb1_increment_seqnum_nonblock(struct tdb1_context *tdb)
   increment the tdb sequence number if the tdb has been opened using
   the TDB_SEQNUM flag
 */
   increment the tdb sequence number if the tdb has been opened using
   the TDB_SEQNUM flag
 */
-static void tdb1_increment_seqnum(struct tdb1_context *tdb)
+static void tdb1_increment_seqnum(struct tdb_context *tdb)
 {
        if (!(tdb->flags & TDB_SEQNUM)) {
                return;
 {
        if (!(tdb->flags & TDB_SEQNUM)) {
                return;
@@ -76,7 +77,7 @@ static int tdb1_key_compare(TDB_DATA key, TDB_DATA data, void *private_data)
 
 /* Returns 0 on fail.  On success, return offset of record, and fills
    in rec */
 
 /* Returns 0 on fail.  On success, return offset of record, and fills
    in rec */
-static tdb1_off_t tdb1_find(struct tdb1_context *tdb, TDB_DATA key, uint32_t hash,
+static tdb1_off_t tdb1_find(struct tdb_context *tdb, TDB_DATA key, uint32_t hash,
                        struct tdb1_record *r)
 {
        tdb1_off_t rec_ptr;
                        struct tdb1_record *r)
 {
        tdb1_off_t rec_ptr;
@@ -111,7 +112,7 @@ static tdb1_off_t tdb1_find(struct tdb1_context *tdb, TDB_DATA key, uint32_t has
 }
 
 /* As tdb1_find, but if you succeed, keep the lock */
 }
 
 /* As tdb1_find, but if you succeed, keep the lock */
-tdb1_off_t tdb1_find_lock_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t hash, int locktype,
+tdb1_off_t tdb1_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, int locktype,
                           struct tdb1_record *rec)
 {
        uint32_t rec_ptr;
                           struct tdb1_record *rec)
 {
        uint32_t rec_ptr;
@@ -123,13 +124,13 @@ tdb1_off_t tdb1_find_lock_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t
        return rec_ptr;
 }
 
        return rec_ptr;
 }
 
-static TDB_DATA _tdb1_fetch(struct tdb1_context *tdb, TDB_DATA key);
+static TDB_DATA _tdb1_fetch(struct tdb_context *tdb, TDB_DATA key);
 
 /* update an entry in place - this only works if the new data size
    is <= the old data size and the key exists.
    on failure return -1.
 */
 
 /* update an entry in place - this only works if the new data size
    is <= the old data size and the key exists.
    on failure return -1.
 */
-static int tdb1_update_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t hash, TDB_DATA dbuf)
+static int tdb1_update_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, TDB_DATA dbuf)
 {
        struct tdb1_record rec;
        tdb1_off_t rec_ptr;
 {
        struct tdb1_record rec;
        tdb1_off_t rec_ptr;
@@ -162,7 +163,7 @@ static int tdb1_update_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t has
                return -1;
        }
 
                return -1;
        }
 
-       if (tdb->methods->tdb1_write(tdb, rec_ptr + sizeof(rec) + rec.key_len,
+       if (tdb->tdb1.io->tdb1_write(tdb, rec_ptr + sizeof(rec) + rec.key_len,
                      dbuf.dptr, dbuf.dsize) == -1)
                return -1;
 
                      dbuf.dptr, dbuf.dsize) == -1)
                return -1;
 
@@ -181,7 +182,7 @@ static int tdb1_update_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t has
  * then the TDB_DATA will have zero length but
  * a non-zero pointer
  */
  * then the TDB_DATA will have zero length but
  * a non-zero pointer
  */
-static TDB_DATA _tdb1_fetch(struct tdb1_context *tdb, TDB_DATA key)
+static TDB_DATA _tdb1_fetch(struct tdb_context *tdb, TDB_DATA key)
 {
        tdb1_off_t rec_ptr;
        struct tdb1_record rec;
 {
        tdb1_off_t rec_ptr;
        struct tdb1_record rec;
@@ -200,39 +201,23 @@ static TDB_DATA _tdb1_fetch(struct tdb1_context *tdb, TDB_DATA key)
        return ret;
 }
 
        return ret;
 }
 
-TDB_DATA tdb1_fetch(struct tdb1_context *tdb, TDB_DATA key)
+enum TDB_ERROR tdb1_fetch(struct tdb_context *tdb, TDB_DATA key, TDB_DATA *data)
 {
 {
-       TDB_DATA ret = _tdb1_fetch(tdb, key);
-
-       return ret;
+       *data = _tdb1_fetch(tdb, key);
+       if (data->dptr == NULL)
+               return tdb->last_error;
+       return TDB_SUCCESS;
 }
 
 }
 
-/*
- * Find an entry in the database and hand the record's data to a parsing
- * function. The parsing function is executed under the chain read lock, so it
- * should be fast and should not block on other syscalls.
- *
- * DON'T CALL OTHER TDB CALLS FROM THE PARSER, THIS MIGHT LEAD TO SEGFAULTS.
- *
- * For mmapped tdb's that do not have a transaction open it points the parsing
- * function directly at the mmap area, it avoids the malloc/memcpy in this
- * case. If a transaction is open or no mmap is available, it has to do
- * malloc/read/parse/free.
- *
- * This is interesting for all readers of potentially large data structures in
- * the tdb records, ldb indexes being one example.
- *
- * Return -1 if the record was not found.
- */
-
-int tdb1_parse_record(struct tdb1_context *tdb, TDB_DATA key,
-                    int (*parser)(TDB_DATA key, TDB_DATA data,
-                                  void *private_data),
-                    void *private_data)
+enum TDB_ERROR tdb1_parse_record(struct tdb_context *tdb, TDB_DATA key,
+                                enum TDB_ERROR (*parser)(TDB_DATA key,
+                                                         TDB_DATA data,
+                                                         void *private_data),
+                                void *private_data)
 {
        tdb1_off_t rec_ptr;
        struct tdb1_record rec;
 {
        tdb1_off_t rec_ptr;
        struct tdb1_record rec;
-       int ret;
+       enum TDB_ERROR ret;
        uint32_t hash;
 
        /* find which hash bucket it is in */
        uint32_t hash;
 
        /* find which hash bucket it is in */
@@ -240,8 +225,7 @@ int tdb1_parse_record(struct tdb1_context *tdb, TDB_DATA key,
 
        if (!(rec_ptr = tdb1_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) {
                /* record not found */
 
        if (!(rec_ptr = tdb1_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) {
                /* record not found */
-               tdb->last_error = TDB_ERR_NOEXIST;
-               return -1;
+               return TDB_ERR_NOEXIST;
        }
 
        ret = tdb1_parse_data(tdb, key, rec_ptr + sizeof(rec) + rec.key_len,
        }
 
        ret = tdb1_parse_data(tdb, key, rec_ptr + sizeof(rec) + rec.key_len,
@@ -258,7 +242,7 @@ int tdb1_parse_record(struct tdb1_context *tdb, TDB_DATA key,
    this doesn't match the conventions in the rest of this module, but is
    compatible with gdbm
 */
    this doesn't match the conventions in the rest of this module, but is
    compatible with gdbm
 */
-static int tdb1_exists_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t hash)
+static int tdb1_exists_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash)
 {
        struct tdb1_record rec;
 
 {
        struct tdb1_record rec;
 
@@ -268,24 +252,25 @@ static int tdb1_exists_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t has
        return 1;
 }
 
        return 1;
 }
 
-int tdb1_exists(struct tdb1_context *tdb, TDB_DATA key)
+int tdb1_exists(struct tdb_context *tdb, TDB_DATA key)
 {
        uint32_t hash = tdb_hash(tdb, key.dptr, key.dsize);
        int ret;
 
 {
        uint32_t hash = tdb_hash(tdb, key.dptr, key.dsize);
        int ret;
 
+       assert(tdb->flags & TDB_VERSION1);
        ret = tdb1_exists_hash(tdb, key, hash);
        return ret;
 }
 
 /* actually delete an entry in the database given the offset */
        ret = tdb1_exists_hash(tdb, key, hash);
        return ret;
 }
 
 /* actually delete an entry in the database given the offset */
-int tdb1_do_delete(struct tdb1_context *tdb, tdb1_off_t rec_ptr, struct tdb1_record *rec)
+int tdb1_do_delete(struct tdb_context *tdb, tdb1_off_t rec_ptr, struct tdb1_record *rec)
 {
        tdb1_off_t last_ptr, i;
        struct tdb1_record lastrec;
 
 {
        tdb1_off_t last_ptr, i;
        struct tdb1_record lastrec;
 
-       if (tdb->read_only || tdb->traverse_read) return -1;
+       if ((tdb->flags & TDB_RDONLY) || tdb->tdb1.traverse_read) return -1;
 
 
-       if (((tdb->traverse_write != 0) && (!TDB1_DEAD(rec))) ||
+       if (((tdb->tdb1.traverse_write != 0) && (!TDB1_DEAD(rec))) ||
            tdb1_write_lock_record(tdb, rec_ptr) == -1) {
                /* Someone traversing here: mark it as dead */
                rec->magic = TDB1_DEAD_MAGIC;
            tdb1_write_lock_record(tdb, rec_ptr) == -1) {
                /* Someone traversing here: mark it as dead */
                rec->magic = TDB1_DEAD_MAGIC;
@@ -313,7 +298,7 @@ int tdb1_do_delete(struct tdb1_context *tdb, tdb1_off_t rec_ptr, struct tdb1_rec
        return 0;
 }
 
        return 0;
 }
 
-static int tdb1_count_dead(struct tdb1_context *tdb, uint32_t hash)
+static int tdb1_count_dead(struct tdb_context *tdb, uint32_t hash)
 {
        int res = 0;
        tdb1_off_t rec_ptr;
 {
        int res = 0;
        tdb1_off_t rec_ptr;
@@ -338,7 +323,7 @@ static int tdb1_count_dead(struct tdb1_context *tdb, uint32_t hash)
 /*
  * Purge all DEAD records from a hash chain
  */
 /*
  * Purge all DEAD records from a hash chain
  */
-static int tdb1_purge_dead(struct tdb1_context *tdb, uint32_t hash)
+static int tdb1_purge_dead(struct tdb_context *tdb, uint32_t hash)
 {
        int res = -1;
        struct tdb1_record rec;
 {
        int res = -1;
        struct tdb1_record rec;
@@ -374,13 +359,13 @@ static int tdb1_purge_dead(struct tdb1_context *tdb, uint32_t hash)
 }
 
 /* delete an entry in the database given a key */
 }
 
 /* delete an entry in the database given a key */
-static int tdb1_delete_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t hash)
+static int tdb1_delete_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash)
 {
        tdb1_off_t rec_ptr;
        struct tdb1_record rec;
        int ret;
 
 {
        tdb1_off_t rec_ptr;
        struct tdb1_record rec;
        int ret;
 
-       if (tdb->max_dead_records != 0) {
+       if (tdb->tdb1.max_dead_records != 0) {
 
                /*
                 * Allow for some dead records per hash chain, mainly for
 
                /*
                 * Allow for some dead records per hash chain, mainly for
@@ -390,7 +375,7 @@ static int tdb1_delete_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t has
                if (tdb1_lock(tdb, TDB1_BUCKET(hash), F_WRLCK) == -1)
                        return -1;
 
                if (tdb1_lock(tdb, TDB1_BUCKET(hash), F_WRLCK) == -1)
                        return -1;
 
-               if (tdb1_count_dead(tdb, hash) >= tdb->max_dead_records) {
+               if (tdb1_count_dead(tdb, hash) >= tdb->tdb1.max_dead_records) {
                        /*
                         * Don't let the per-chain freelist grow too large,
                         * delete all existing dead records
                        /*
                         * Don't let the per-chain freelist grow too large,
                         * delete all existing dead records
@@ -427,11 +412,12 @@ static int tdb1_delete_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t has
        return ret;
 }
 
        return ret;
 }
 
-int tdb1_delete(struct tdb1_context *tdb, TDB_DATA key)
+int tdb1_delete(struct tdb_context *tdb, TDB_DATA key)
 {
        uint32_t hash = tdb_hash(tdb, key.dptr, key.dsize);
        int ret;
 
 {
        uint32_t hash = tdb_hash(tdb, key.dptr, key.dsize);
        int ret;
 
+       assert(tdb->flags & TDB_VERSION1);
        ret = tdb1_delete_hash(tdb, key, hash);
        return ret;
 }
        ret = tdb1_delete_hash(tdb, key, hash);
        return ret;
 }
@@ -439,7 +425,7 @@ int tdb1_delete(struct tdb1_context *tdb, TDB_DATA key)
 /*
  * See if we have a dead record around with enough space
  */
 /*
  * See if we have a dead record around with enough space
  */
-static tdb1_off_t tdb1_find_dead(struct tdb1_context *tdb, uint32_t hash,
+static tdb1_off_t tdb1_find_dead(struct tdb_context *tdb, uint32_t hash,
                               struct tdb1_record *r, tdb1_len_t length)
 {
        tdb1_off_t rec_ptr;
                               struct tdb1_record *r, tdb1_len_t length)
 {
        tdb1_off_t rec_ptr;
@@ -465,7 +451,7 @@ static tdb1_off_t tdb1_find_dead(struct tdb1_context *tdb, uint32_t hash,
        return 0;
 }
 
        return 0;
 }
 
-static int _tdb1_store(struct tdb1_context *tdb, TDB_DATA key,
+static int _tdb1_store(struct tdb_context *tdb, TDB_DATA key,
                       TDB_DATA dbuf, int flag, uint32_t hash)
 {
        struct tdb1_record rec;
                       TDB_DATA dbuf, int flag, uint32_t hash)
 {
        struct tdb1_record rec;
@@ -512,7 +498,7 @@ static int _tdb1_store(struct tdb1_context *tdb, TDB_DATA key,
        if (dbuf.dsize)
                memcpy(p+key.dsize, dbuf.dptr, dbuf.dsize);
 
        if (dbuf.dsize)
                memcpy(p+key.dsize, dbuf.dptr, dbuf.dsize);
 
-       if (tdb->max_dead_records != 0) {
+       if (tdb->tdb1.max_dead_records != 0) {
                /*
                 * Allow for some dead records per hash chain, look if we can
                 * find one that can hold the new record. We need enough space
                /*
                 * Allow for some dead records per hash chain, look if we can
                 * find one that can hold the new record. We need enough space
@@ -529,7 +515,7 @@ static int _tdb1_store(struct tdb1_context *tdb, TDB_DATA key,
                        rec.full_hash = hash;
                        rec.magic = TDB1_MAGIC;
                        if (tdb1_rec_write(tdb, rec_ptr, &rec) == -1
                        rec.full_hash = hash;
                        rec.magic = TDB1_MAGIC;
                        if (tdb1_rec_write(tdb, rec_ptr, &rec) == -1
-                           || tdb->methods->tdb1_write(
+                           || tdb->tdb1.io->tdb1_write(
                                    tdb, rec_ptr + sizeof(rec),
                                    p, key.dsize + dbuf.dsize) == -1) {
                                goto fail;
                                    tdb, rec_ptr + sizeof(rec),
                                    p, key.dsize + dbuf.dsize) == -1) {
                                goto fail;
@@ -548,7 +534,7 @@ static int _tdb1_store(struct tdb1_context *tdb, TDB_DATA key,
                goto fail;
        }
 
                goto fail;
        }
 
-       if ((tdb->max_dead_records != 0)
+       if ((tdb->tdb1.max_dead_records != 0)
            && (tdb1_purge_dead(tdb, hash) == -1)) {
                tdb1_unlock(tdb, -1, F_WRLCK);
                goto fail;
            && (tdb1_purge_dead(tdb, hash) == -1)) {
                tdb1_unlock(tdb, -1, F_WRLCK);
                goto fail;
@@ -574,7 +560,7 @@ static int _tdb1_store(struct tdb1_context *tdb, TDB_DATA key,
 
        /* write out and point the top of the hash chain at it */
        if (tdb1_rec_write(tdb, rec_ptr, &rec) == -1
 
        /* write out and point the top of the hash chain at it */
        if (tdb1_rec_write(tdb, rec_ptr, &rec) == -1
-           || tdb->methods->tdb1_write(tdb, rec_ptr+sizeof(rec), p, key.dsize+dbuf.dsize)==-1
+           || tdb->tdb1.io->tdb1_write(tdb, rec_ptr+sizeof(rec), p, key.dsize+dbuf.dsize)==-1
            || tdb1_ofs_write(tdb, TDB1_HASH_TOP(hash), &rec_ptr) == -1) {
                /* Need to tdb1_unallocate() here */
                goto fail;
            || tdb1_ofs_write(tdb, TDB1_HASH_TOP(hash), &rec_ptr) == -1) {
                /* Need to tdb1_unallocate() here */
                goto fail;
@@ -596,12 +582,14 @@ static int _tdb1_store(struct tdb1_context *tdb, TDB_DATA key,
 
    return 0 on success, -1 on failure
 */
 
    return 0 on success, -1 on failure
 */
-int tdb1_store(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
+int tdb1_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
 {
        uint32_t hash;
        int ret;
 
 {
        uint32_t hash;
        int ret;
 
-       if (tdb->read_only || tdb->traverse_read) {
+       assert(tdb->flags & TDB_VERSION1);
+
+       if ((tdb->flags & TDB_RDONLY) || tdb->tdb1.traverse_read) {
                tdb->last_error = TDB_ERR_RDONLY;
                return -1;
        }
                tdb->last_error = TDB_ERR_RDONLY;
                return -1;
        }
@@ -617,12 +605,14 @@ int tdb1_store(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
 }
 
 /* Append to an entry. Create if not exist. */
 }
 
 /* Append to an entry. Create if not exist. */
-int tdb1_append(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA new_dbuf)
+int tdb1_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf)
 {
        uint32_t hash;
        TDB_DATA dbuf;
        int ret = -1;
 
 {
        uint32_t hash;
        TDB_DATA dbuf;
        int ret = -1;
 
+       assert(tdb->flags & TDB_VERSION1);
+
        /* find which hash bucket it is in */
        hash = tdb_hash(tdb, key.dptr, key.dsize);
        if (tdb1_lock(tdb, TDB1_BUCKET(hash), F_WRLCK) == -1)
        /* find which hash bucket it is in */
        hash = tdb_hash(tdb, key.dptr, key.dsize);
        if (tdb1_lock(tdb, TDB1_BUCKET(hash), F_WRLCK) == -1)
@@ -673,7 +663,7 @@ failed:
   The aim of this sequence number is to allow for a very lightweight
   test of a possible tdb change.
 */
   The aim of this sequence number is to allow for a very lightweight
   test of a possible tdb change.
 */
-int tdb1_get_seqnum(struct tdb1_context *tdb)
+int tdb1_get_seqnum(struct tdb_context *tdb)
 {
        tdb1_off_t seqnum=0;
 
 {
        tdb1_off_t seqnum=0;
 
@@ -681,17 +671,12 @@ int tdb1_get_seqnum(struct tdb1_context *tdb)
        return seqnum;
 }
 
        return seqnum;
 }
 
-int tdb1_hash_size(struct tdb1_context *tdb)
-{
-       return tdb->header.hash_size;
-}
-
 
 /*
   add a region of the file to the freelist. Length is the size of the region in bytes,
   which includes the free list header that needs to be added
  */
 
 /*
   add a region of the file to the freelist. Length is the size of the region in bytes,
   which includes the free list header that needs to be added
  */
-static int tdb1_free_region(struct tdb1_context *tdb, tdb1_off_t offset, ssize_t length)
+static int tdb1_free_region(struct tdb_context *tdb, tdb1_off_t offset, ssize_t length)
 {
        struct tdb1_record rec;
        if (length <= sizeof(rec)) {
 {
        struct tdb1_record rec;
        if (length <= sizeof(rec)) {
@@ -721,7 +706,7 @@ static int tdb1_free_region(struct tdb1_context *tdb, tdb1_off_t offset, ssize_t
 
   This code carefully steps around the recovery area, leaving it alone
  */
 
   This code carefully steps around the recovery area, leaving it alone
  */
-int tdb1_wipe_all(struct tdb1_context *tdb)
+int tdb1_wipe_all(struct tdb_context *tdb)
 {
        int i;
        tdb1_off_t offset = 0;
 {
        int i;
        tdb1_off_t offset = 0;
@@ -729,7 +714,7 @@ int tdb1_wipe_all(struct tdb1_context *tdb)
        tdb1_off_t recovery_head;
        tdb1_len_t recovery_size = 0;
 
        tdb1_off_t recovery_head;
        tdb1_len_t recovery_size = 0;
 
-       if (tdb1_lockall(tdb) != 0) {
+       if (tdb_lockall(tdb) != TDB_SUCCESS) {
                return -1;
        }
 
                return -1;
        }
 
@@ -746,7 +731,7 @@ int tdb1_wipe_all(struct tdb1_context *tdb)
 
        if (recovery_head != 0) {
                struct tdb1_record rec;
 
        if (recovery_head != 0) {
                struct tdb1_record rec;
-               if (tdb->methods->tdb1_read(tdb, recovery_head, &rec, sizeof(rec), TDB1_DOCONV()) == -1) {
+               if (tdb->tdb1.io->tdb1_read(tdb, recovery_head, &rec, sizeof(rec), TDB1_DOCONV()) == -1) {
                        tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
                                   "tdb1_wipe_all: failed to read recovery record");
                        return -1;
                        tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
                                   "tdb1_wipe_all: failed to read recovery record");
                        return -1;
@@ -755,7 +740,7 @@ int tdb1_wipe_all(struct tdb1_context *tdb)
        }
 
        /* wipe the hashes */
        }
 
        /* wipe the hashes */
-       for (i=0;i<tdb->header.hash_size;i++) {
+       for (i=0;i<tdb->tdb1.header.hash_size;i++) {
                if (tdb1_ofs_write(tdb, TDB1_HASH_TOP(i), &offset) == -1) {
                        tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
                                   "tdb1_wipe_all: failed to write hash %d", i);
                if (tdb1_ofs_write(tdb, TDB1_HASH_TOP(i), &offset) == -1) {
                        tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
                                   "tdb1_wipe_all: failed to write hash %d", i);
@@ -774,8 +759,8 @@ int tdb1_wipe_all(struct tdb1_context *tdb)
           for the recovery area */
        if (recovery_size == 0) {
                /* the simple case - the whole file can be used as a freelist */
           for the recovery area */
        if (recovery_size == 0) {
                /* the simple case - the whole file can be used as a freelist */
-               data_len = (tdb->file->map_size - TDB1_DATA_START(tdb->header.hash_size));
-               if (tdb1_free_region(tdb, TDB1_DATA_START(tdb->header.hash_size), data_len) != 0) {
+               data_len = (tdb->file->map_size - TDB1_DATA_START(tdb->tdb1.header.hash_size));
+               if (tdb1_free_region(tdb, TDB1_DATA_START(tdb->tdb1.header.hash_size), data_len) != 0) {
                        goto failed;
                }
        } else {
                        goto failed;
                }
        } else {
@@ -787,8 +772,8 @@ int tdb1_wipe_all(struct tdb1_context *tdb)
                   move the recovery area or we risk subtle data
                   corruption
                */
                   move the recovery area or we risk subtle data
                   corruption
                */
-               data_len = (recovery_head - TDB1_DATA_START(tdb->header.hash_size));
-               if (tdb1_free_region(tdb, TDB1_DATA_START(tdb->header.hash_size), data_len) != 0) {
+               data_len = (recovery_head - TDB1_DATA_START(tdb->tdb1.header.hash_size));
+               if (tdb1_free_region(tdb, TDB1_DATA_START(tdb->tdb1.header.hash_size), data_len) != 0) {
                        goto failed;
                }
                /* and the 2nd free list entry after the recovery area - if any */
                        goto failed;
                }
                /* and the 2nd free list entry after the recovery area - if any */
@@ -798,28 +783,23 @@ int tdb1_wipe_all(struct tdb1_context *tdb)
                }
        }
 
                }
        }
 
-       if (tdb1_unlockall(tdb) != 0) {
-               tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
-                          "tdb1_wipe_all: failed to unlock");
-               goto failed;
-       }
-
+       tdb_unlockall(tdb);
        return 0;
 
 failed:
        return 0;
 
 failed:
-       tdb1_unlockall(tdb);
+       tdb_unlockall(tdb);
        return -1;
 }
 
 struct traverse_state {
        enum TDB_ERROR error;
        return -1;
 }
 
 struct traverse_state {
        enum TDB_ERROR error;
-       struct tdb1_context *dest_db;
+       struct tdb_context *dest_db;
 };
 
 /*
   traverse function for repacking
  */
 };
 
 /*
   traverse function for repacking
  */
-static int repack_traverse(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA data, void *private_data)
+static int repack_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *private_data)
 {
        struct traverse_state *state = (struct traverse_state *)private_data;
        if (tdb1_store(state->dest_db, key, data, TDB_INSERT) != 0) {
 {
        struct traverse_state *state = (struct traverse_state *)private_data;
        if (tdb1_store(state->dest_db, key, data, TDB_INSERT) != 0) {
@@ -832,10 +812,15 @@ static int repack_traverse(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA data
 /*
   repack a tdb
  */
 /*
   repack a tdb
  */
-int tdb1_repack(struct tdb1_context *tdb)
+int tdb1_repack(struct tdb_context *tdb)
 {
 {
-       struct tdb1_context *tmp_db;
+       struct tdb_context *tmp_db;
        struct traverse_state state;
        struct traverse_state state;
+       union tdb_attribute hsize;
+
+       hsize.base.attr = TDB_ATTRIBUTE_TDB1_HASHSIZE;
+       hsize.base.next = NULL;
+       hsize.tdb1_hashsize.hsize = tdb->tdb1.header.hash_size;
 
        if (tdb1_transaction_start(tdb) != 0) {
                tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
 
        if (tdb1_transaction_start(tdb) != 0) {
                tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
@@ -843,7 +828,7 @@ int tdb1_repack(struct tdb1_context *tdb)
                return -1;
        }
 
                return -1;
        }
 
-       tmp_db = tdb1_open("tmpdb", tdb1_hash_size(tdb), TDB_INTERNAL, O_RDWR|O_CREAT, 0);
+       tmp_db = tdb_open("tmpdb", TDB_INTERNAL, O_RDWR|O_CREAT, 0, &hsize);
        if (tmp_db == NULL) {
                tdb->last_error = tdb_logerr(tdb, TDB_ERR_OOM, TDB_LOG_ERROR,
                                        __location__ " Failed to create tmp_db");
        if (tmp_db == NULL) {
                tdb->last_error = tdb_logerr(tdb, TDB_ERR_OOM, TDB_LOG_ERROR,
                                        __location__ " Failed to create tmp_db");
@@ -854,11 +839,11 @@ int tdb1_repack(struct tdb1_context *tdb)
        state.error = TDB_SUCCESS;
        state.dest_db = tmp_db;
 
        state.error = TDB_SUCCESS;
        state.dest_db = tmp_db;
 
-       if (tdb1_traverse_read(tdb, repack_traverse, &state) == -1) {
+       if (tdb1_traverse(tdb, repack_traverse, &state) == -1) {
                tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
                           __location__ " Failed to traverse copying out");
                tdb1_transaction_cancel(tdb);
                tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
                           __location__ " Failed to traverse copying out");
                tdb1_transaction_cancel(tdb);
-               tdb1_close(tmp_db);
+               tdb_close(tmp_db);
                return -1;
        }
 
                return -1;
        }
 
@@ -866,7 +851,7 @@ int tdb1_repack(struct tdb1_context *tdb)
                tdb->last_error = tdb_logerr(tdb, state.error, TDB_LOG_ERROR,
                                        __location__ " Error during traversal");
                tdb1_transaction_cancel(tdb);
                tdb->last_error = tdb_logerr(tdb, state.error, TDB_LOG_ERROR,
                                        __location__ " Error during traversal");
                tdb1_transaction_cancel(tdb);
-               tdb1_close(tmp_db);
+               tdb_close(tmp_db);
                return -1;
        }
 
                return -1;
        }
 
@@ -874,18 +859,18 @@ int tdb1_repack(struct tdb1_context *tdb)
                tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
                           __location__ " Failed to wipe database\n");
                tdb1_transaction_cancel(tdb);
                tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
                           __location__ " Failed to wipe database\n");
                tdb1_transaction_cancel(tdb);
-               tdb1_close(tmp_db);
+               tdb_close(tmp_db);
                return -1;
        }
 
        state.error = TDB_SUCCESS;
        state.dest_db = tdb;
 
                return -1;
        }
 
        state.error = TDB_SUCCESS;
        state.dest_db = tdb;
 
-       if (tdb1_traverse_read(tmp_db, repack_traverse, &state) == -1) {
+       if (tdb1_traverse(tmp_db, repack_traverse, &state) == -1) {
                tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
                           __location__ " Failed to traverse copying back");
                tdb1_transaction_cancel(tdb);
                tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
                           __location__ " Failed to traverse copying back");
                tdb1_transaction_cancel(tdb);
-               tdb1_close(tmp_db);
+               tdb_close(tmp_db);
                return -1;
        }
 
                return -1;
        }
 
@@ -893,11 +878,11 @@ int tdb1_repack(struct tdb1_context *tdb)
                tdb->last_error = tdb_logerr(tdb, state.error, TDB_LOG_ERROR,
                                        __location__ " Error during second traversal");
                tdb1_transaction_cancel(tdb);
                tdb->last_error = tdb_logerr(tdb, state.error, TDB_LOG_ERROR,
                                        __location__ " Error during second traversal");
                tdb1_transaction_cancel(tdb);
-               tdb1_close(tmp_db);
+               tdb_close(tmp_db);
                return -1;
        }
 
                return -1;
        }
 
-       tdb1_close(tmp_db);
+       tdb_close(tmp_db);
 
        if (tdb1_transaction_commit(tdb) != 0) {
                tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
 
        if (tdb1_transaction_commit(tdb) != 0) {
                tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,