X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftdb2%2Fopen.c;h=5d5eff1394b870233e90d22375438cc4be591cfc;hp=555df9512608c1ba0269461e6f5dc823de9ab4f6;hb=49475d68deecd0b31597ed6094229171d2699b11;hpb=1a0c636bc38213bd0322db47529f78f2dc22ffdd diff --git a/ccan/tdb2/open.c b/ccan/tdb2/open.c index 555df951..5d5eff13 100644 --- a/ccan/tdb2/open.c +++ b/ccan/tdb2/open.c @@ -16,7 +16,6 @@ License along with this library; if not, see . */ #include "private.h" -#include #include /* all tdbs, to detect double-opens (fcntl file don't nest!) */ @@ -210,6 +209,7 @@ enum TDB_ERROR tdb_set_attribute(struct tdb_context *tdb, case TDB_ATTRIBUTE_HASH: case TDB_ATTRIBUTE_SEED: case TDB_ATTRIBUTE_OPENHOOK: + case TDB_ATTRIBUTE_TDB1_HASHSIZE: return tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, @@ -219,7 +219,9 @@ enum TDB_ERROR tdb_set_attribute(struct tdb_context *tdb, ? "TDB_ATTRIBUTE_HASH" : attr->base.attr == TDB_ATTRIBUTE_SEED ? "TDB_ATTRIBUTE_SEED" - : "TDB_ATTRIBUTE_OPENHOOK"); + : attr->base.attr == TDB_ATTRIBUTE_OPENHOOK + ? "TDB_ATTRIBUTE_OPENHOOK" + : "TDB_ATTRIBUTE_TDB1_HASHSIZE"); case TDB_ATTRIBUTE_STATS: return tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, @@ -242,16 +244,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) { @@ -287,6 +279,16 @@ enum TDB_ERROR tdb_get_attribute(struct tdb_context *tdb, attr->flock.unlock = tdb->unlock_fn; attr->flock.data = tdb->lock_data; break; + case TDB_ATTRIBUTE_TDB1_HASHSIZE: + if (!(tdb->flags & TDB_VERSION1)) + return tdb->last_error + = tdb_logerr(tdb, TDB_ERR_EINVAL, + TDB_LOG_USE_ERROR, + "tdb_get_attribute:" + " cannot get TDB_ATTRIBUTE_TDB1_HASHSIZE" + " on TDB2 tdb."); + attr->tdb1_hashsize.hsize = tdb->tdb1.header.hash_size; + break; default: return tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, @@ -311,11 +313,14 @@ void tdb_unset_attribute(struct tdb_context *tdb, break; case TDB_ATTRIBUTE_HASH: case TDB_ATTRIBUTE_SEED: + case TDB_ATTRIBUTE_TDB1_HASHSIZE: tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, "tdb_unset_attribute: cannot unset %s after opening", type == TDB_ATTRIBUTE_HASH ? "TDB_ATTRIBUTE_HASH" - : "TDB_ATTRIBUTE_SEED"); + : type == TDB_ATTRIBUTE_SEED + ? "TDB_ATTRIBUTE_SEED" + : "TDB_ATTRIBUTE_TDB1_HASHSIZE"); break; case TDB_ATTRIBUTE_STATS: tdb_logerr(tdb, TDB_ERR_EINVAL, @@ -347,6 +352,7 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags, ssize_t rlen; struct tdb_header hdr; struct tdb_attribute_seed *seed = NULL; + struct tdb_attribute_tdb1_hashsize *hsize_attr = NULL; tdb_bool_err berr; enum TDB_ERROR ecode; int openlock; @@ -363,22 +369,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) { @@ -393,6 +399,9 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags, tdb->openhook = attr->openhook.fn; tdb->openhook_data = attr->openhook.data; break; + case TDB_ATTRIBUTE_TDB1_HASHSIZE: + hsize_attr = &attr->tdb1_hashsize; + break; default: /* These are set as normal. */ ecode = tdb_set_attribute(tdb, attr); @@ -410,6 +419,18 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags, goto fail; } + if (hsize_attr) { + if (!(tdb_flags & TDB_VERSION1) || + (!(tdb_flags & TDB_INTERNAL) && !(open_flags & O_CREAT))) { + ecode = tdb_logerr(tdb, TDB_ERR_EINVAL, + TDB_LOG_USE_ERROR, + "tdb_open: can only use" + " TDB_ATTRIBUTE_TDB1_HASHSIZE when" + " creating a TDB_VERSION1 tdb"); + goto fail; + } + } + if ((open_flags & O_ACCMODE) == O_WRONLY) { ecode = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, "tdb_open: can't open tdb %s write-only", @@ -573,7 +594,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; @@ -655,7 +676,7 @@ int tdb_close(struct tdb_context *tdb) tdb_trace(tdb, "tdb_close"); - if (tdb->transaction) { + if (tdb->tdb2.transaction) { tdb_transaction_cancel(tdb); }