X-Git-Url: https://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Ftdb2%2Flock.c;h=c7c449abc1a37091824563475b7aa7558f89e759;hb=9faf17435f1f5ce3c7046a738c45b60597838c03;hp=2b00584580810ad9aca0ae24dd6f880bd58d0796;hpb=2c56e4d9ec516aceb9c5b26ceebd6d99361855c5;p=ccan diff --git a/ccan/tdb2/lock.c b/ccan/tdb2/lock.c index 2b005845..c7c449ab 100644 --- a/ccan/tdb2/lock.c +++ b/ccan/tdb2/lock.c @@ -255,13 +255,18 @@ static int tdb_nest_lock(struct tdb_context *tdb, tdb_off_t offset, int ltype, { struct tdb_lock_type *new_lck; - if (offset >= TDB_HASH_LOCK_START + (1ULL << tdb->header.v.hash_bits) - + (tdb->header.v.num_zones * (tdb->header.v.free_buckets+1))) { - tdb->ecode = TDB_ERR_LOCK; - tdb->log(tdb, TDB_DEBUG_FATAL, tdb->log_priv, - "tdb_lock: invalid offset %llu for ltype=%d\n", - (long long)offset, ltype); - return -1; + /* Header is not valid for open lock; valgrind complains. */ + if (offset >= TDB_HASH_LOCK_START) { + if (offset > TDB_HASH_LOCK_START + + (1ULL << tdb->header.v.hash_bits) + + (tdb->header.v.num_zones + * (tdb->header.v.free_buckets+1))) { + tdb->ecode = TDB_ERR_LOCK; + tdb->log(tdb, TDB_DEBUG_FATAL, tdb->log_priv, + "tdb_lock: invalid offset %llu ltype=%d\n", + (long long)offset, ltype); + return -1; + } } if (tdb->flags & TDB_NOLOCK) return 0; @@ -719,7 +724,8 @@ void tdb_unlock_free_list(struct tdb_context *tdb, tdb_off_t flist) + flist, F_WRLCK); } -#if 0 +/* Even if the entry isn't in this hash bucket, you'd have to lock this + * bucket to find it. */ static int chainlock(struct tdb_context *tdb, const TDB_DATA *key, int ltype, enum tdb_lock_flags waitflag, const char *func) @@ -739,6 +745,14 @@ int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key) return chainlock(tdb, &key, F_WRLCK, TDB_LOCK_WAIT, "tdb_chainlock"); } +int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key) +{ + uint64_t h = tdb_hash(tdb, key.dptr, key.dsize); + tdb_trace_1rec(tdb, "tdb_chainunlock", key); + return tdb_unlock_list(tdb, h, F_WRLCK); +} + +#if 0 /* lock/unlock one hash chain, non-blocking. This is meant to be used to reduce contention - it cannot guarantee how many records will be locked */ @@ -748,14 +762,6 @@ int tdb_chainlock_nonblock(struct tdb_context *tdb, TDB_DATA key) "tdb_chainlock_nonblock"); } -int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key) -{ - uint64_t h = tdb_hash(tdb, key.dptr, key.dsize); - tdb_trace_1rec(tdb, "tdb_chainunlock", key); - return tdb_unlock_list(tdb, h & ((1ULL << tdb->header.v.hash_bits)-1), - F_WRLCK); -} - int tdb_chainlock_read(struct tdb_context *tdb, TDB_DATA key) { return chainlock(tdb, &key, F_RDLCK, TDB_LOCK_WAIT,