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);
}