X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftdb2%2Fopen.c;h=49804acfba427236382eb5e76d9790e05833eea7;hp=277a95f9e8ba7bb72caed6ac434f7ccb798ebc1c;hb=c8f6f8c2dea76042f74c02eff048847e62adcca6;hpb=937d0babe99dcd315040a9e48430140e63e4a7df diff --git a/ccan/tdb2/open.c b/ccan/tdb2/open.c index 277a95f9..49804acf 100644 --- a/ccan/tdb2/open.c +++ b/ccan/tdb2/open.c @@ -16,23 +16,22 @@ License along with this library; if not, see . */ #include "private.h" -#include #include -/* all lock info, to detect double-opens (fcntl file don't nest!) */ -static struct tdb_file *files = NULL; +/* all tdbs, to detect double-opens (fcntl file don't nest!) */ +static struct tdb_context *tdbs = NULL; static struct tdb_file *find_file(dev_t device, ino_t ino) { - struct tdb_file *i; + struct tdb_context *i; - for (i = files; i; i = i->next) { - if (i->device == device && i->inode == ino) { - i->refcnt++; - break; + for (i = tdbs; i; i = i->next) { + if (i->file->device == device && i->file->inode == ino) { + i->file->refcnt++; + return i->file; } } - return i; + return NULL; } static bool read_all(int fd, void *buf, size_t len) @@ -242,16 +241,6 @@ enum TDB_ERROR tdb_set_attribute(struct tdb_context *tdb, return TDB_SUCCESS; } -static uint64_t jenkins_hash(const void *key, size_t length, uint64_t seed, - void *unused) -{ - uint64_t ret; - /* hash64_stable assumes lower bits are more important; they are a - * slightly better hash. We use the upper bits first, so swap them. */ - ret = hash64_stable((const unsigned char *)key, length, seed); - return (ret >> 32) | (ret << 32); -} - enum TDB_ERROR tdb_get_attribute(struct tdb_context *tdb, union tdb_attribute *attr) { @@ -363,22 +352,22 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags, } else { tdb->name = NULL; } - tdb->direct_access = 0; tdb->flags = tdb_flags; tdb->log_fn = NULL; - tdb->transaction = NULL; - tdb->access = NULL; tdb->open_flags = open_flags; tdb->last_error = TDB_SUCCESS; tdb->file = NULL; tdb->openhook = NULL; tdb->lock_fn = tdb_fcntl_lock; tdb->unlock_fn = tdb_fcntl_unlock; - tdb->hash_fn = jenkins_hash; + tdb->hash_fn = tdb_jenkins_hash; memset(&tdb->stats, 0, sizeof(tdb->stats)); tdb->stats.base.attr = TDB_ATTRIBUTE_STATS; tdb->stats.size = sizeof(tdb->stats); tdb_io_init(tdb); + tdb->tdb2.direct_access = 0; + tdb->tdb2.transaction = NULL; + tdb->tdb2.access = NULL; while (attr) { switch (attr->base.attr) { @@ -483,7 +472,6 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags, goto fail; } - tdb->file->next = files; tdb->file->fd = fd; tdb->file->device = st.st_dev; tdb->file->inode = st.st_ino; @@ -574,7 +562,7 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags, tdb_unlock_open(tdb, openlock); /* This make sure we have current map_size and mmap. */ - ecode = tdb->methods->oob(tdb, tdb->file->map_size + 1, true); + ecode = tdb->tdb2.io->oob(tdb, tdb->file->map_size + 1, true); if (unlikely(ecode != TDB_SUCCESS)) goto fail; @@ -596,9 +584,8 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags, goto fail; } - /* Add to linked list if we're new. */ - if (tdb->file->refcnt == 1) - files = tdb->file; + tdb->next = tdbs; + tdbs = tdb; return tdb; fail: @@ -653,10 +640,11 @@ fail_errno: int tdb_close(struct tdb_context *tdb) { int ret = 0; + struct tdb_context **i; tdb_trace(tdb, "tdb_close"); - if (tdb->transaction) { + if (tdb->tdb2.transaction) { tdb_transaction_cancel(tdb); } @@ -667,24 +655,22 @@ int tdb_close(struct tdb_context *tdb) tdb_munmap(tdb->file); } if (tdb->file) { - struct tdb_file **i; - tdb_lock_cleanup(tdb); if (--tdb->file->refcnt == 0) { ret = close(tdb->file->fd); - - /* Remove from files list */ - for (i = &files; *i; i = &(*i)->next) { - if (*i == tdb->file) { - *i = tdb->file->next; - break; - } - } free(tdb->file->lockrecs); free(tdb->file); } } + /* Remove from tdbs list */ + for (i = &tdbs; *i; i = &(*i)->next) { + if (*i == tdb) { + *i = tdb->next; + break; + } + } + #ifdef TDB_TRACE close(tdb->tracefd); #endif @@ -692,3 +678,13 @@ int tdb_close(struct tdb_context *tdb) return ret; } + +void tdb_foreach_(int (*fn)(struct tdb_context *, void *), void *p) +{ + struct tdb_context *i; + + for (i = tdbs; i; i = i->next) { + if (fn(i, p) != 0) + break; + } +}