X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftdb2%2Ftdb.c;h=bd5c268173dcda9b11e1889957b64274c03773d9;hp=c0561fb9fe1f2511797aa5604d368721a3a57f61;hb=fe55330a;hpb=d70577b6aff24ccf6815896509dabb8c9ac07904 diff --git a/ccan/tdb2/tdb.c b/ccan/tdb2/tdb.c index c0561fb9..bd5c2681 100644 --- a/ccan/tdb2/tdb.c +++ b/ccan/tdb2/tdb.c @@ -103,6 +103,7 @@ static int tdb_new_database(struct tdb_context *tdb, 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)); @@ -110,8 +111,9 @@ static int tdb_new_database(struct tdb_context *tdb, /* 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)); @@ -175,6 +177,7 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags, tdb->log = null_log_fn; tdb->log_priv = NULL; tdb->transaction = NULL; + tdb->stats = NULL; tdb_hash_init(tdb); tdb_io_init(tdb); tdb_lock_init(tdb); @@ -192,6 +195,12 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags, case TDB_ATTRIBUTE_SEED: seed = &attr->seed; break; + case TDB_ATTRIBUTE_STATS: + tdb->stats = &attr->stats; + /* They have stats we don't know about? Tell them. */ + if (tdb->stats->size > sizeof(attr->stats)) + tdb->stats->size = sizeof(attr->stats); + break; default: tdb->log(tdb, TDB_DEBUG_ERROR, tdb->log_priv, "tdb_open: unknown attribute type %u\n", @@ -245,7 +254,7 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags, 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)); @@ -313,6 +322,12 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags, /* 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; @@ -356,7 +371,7 @@ static int update_rec_hdr(struct tdb_context *tdb, { 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)); @@ -378,6 +393,7 @@ static int replace_data(struct tdb_context *tdb, /* We didn't like the existing one: remove it. */ if (old_off) { + add_stat(tdb, frees, 1); add_free_record(tdb, old_off, sizeof(struct tdb_used_record) + key.dsize + old_room); @@ -574,6 +590,7 @@ int tdb_delete(struct tdb_context *tdb, struct tdb_data key) goto unlock_err; /* Free the deleted entry. */ + add_stat(tdb, frees, 1); if (add_free_record(tdb, off, sizeof(struct tdb_used_record) + rec_key_length(&rec) @@ -594,12 +611,11 @@ int tdb_close(struct tdb_context *tdb) 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)