sizeof(newdb.hdr.hash_test),
newdb.hdr.hash_seed,
tdb->hash_priv);
+ newdb.hdr.recovery = 0;
memset(newdb.hdr.reserved, 0, sizeof(newdb.hdr.reserved));
/* Initial hashes are empty. */
memset(newdb.hdr.hashtable, 0, sizeof(newdb.hdr.hashtable));
/* Free is empty. */
newdb.hdr.free_list = offsetof(struct new_database, flist);
memset(&newdb.flist, 0, sizeof(newdb.flist));
- set_header(NULL, &newdb.flist.hdr, 0,
- sizeof(newdb.flist.buckets), sizeof(newdb.flist.buckets), 1);
+ set_used_header(NULL, &newdb.flist.hdr, 0,
+ sizeof(newdb.flist) - sizeof(newdb.flist.hdr),
+ sizeof(newdb.flist) - sizeof(newdb.flist.hdr), 1);
/* Magic food */
memset(newdb.hdr.magic_food, 0, sizeof(newdb.hdr.magic_food));
fcntl(tdb->fd, F_SETFD, v | FD_CLOEXEC);
/* ensure there is only one process initialising at once */
- if (tdb_lock_open(tdb) == -1) {
+ if (tdb_lock_open(tdb, TDB_LOCK_WAIT|TDB_LOCK_NOCHECK) == -1) {
tdb->log(tdb, TDB_DEBUG_ERROR, tdb->log_priv,
"tdb_open: failed to get open lock on %s: %s\n",
name, strerror(errno));
/* This make sure we have current map_size and mmap. */
tdb->methods->oob(tdb, tdb->map_size + 1, true);
+ /* Now it's fully formed, recover if necessary. */
+ if (tdb_needs_recovery(tdb) && tdb_lock_and_recover(tdb) == -1) {
+ errno = EIO;
+ goto fail;
+ }
+
if (tdb_flist_init(tdb) == -1)
goto fail;
{
uint64_t dataroom = rec_data_length(rec) + rec_extra_padding(rec);
- if (set_header(tdb, rec, keylen, datalen, keylen + dataroom, h))
+ if (set_used_header(tdb, rec, keylen, datalen, keylen + dataroom, h))
return -1;
return tdb_write_convert(tdb, off, rec, sizeof(*rec));
struct tdb_context **i;
int ret = 0;
- /* FIXME:
+ tdb_trace(tdb, "tdb_close");
+
if (tdb->transaction) {
tdb_transaction_cancel(tdb);
}
- */
- tdb_trace(tdb, "tdb_close");
if (tdb->map_ptr) {
if (tdb->flags & TDB_INTERNAL)