/* lock/unlock entire database. It can only be upgradable if you have some
* other way of guaranteeing exclusivity (ie. transaction write lock).
* Note that we don't lock the free chains: noone can get those locks
- * without a hash chain lock first. */
+ * without a hash chain lock first.
+ * The header *will be* up to date once this returns success. */
int tdb_allrecord_lock(struct tdb_context *tdb, int ltype,
enum tdb_lock_flags flags, bool upgradable)
{
return -1;
}
+ tdb->allrecord_lock.count = 1;
+ /* If it's upgradable, it's actually exclusive so we can treat
+ * it as a write lock. */
+ tdb->allrecord_lock.ltype = upgradable ? F_WRLCK : ltype;
+ tdb->allrecord_lock.off = upgradable;
+
/* Now we re-check header, holding lock. */
if (unlikely(update_header(tdb))) {
- tdb_brunlock(tdb, ltype, TDB_HASH_LOCK_START, hash_size);
+ tdb_allrecord_unlock(tdb, ltype);
goto again;
}
/* Now check for needing recovery. */
if (unlikely(tdb_needs_recovery(tdb))) {
- tdb_brunlock(tdb, ltype, TDB_HASH_LOCK_START, hash_size);
+ tdb_allrecord_unlock(tdb, ltype);
if (tdb_lock_and_recover(tdb) == -1) {
return -1;
}
goto again;
}
-
- tdb->allrecord_lock.count = 1;
- /* If it's upgradable, it's actually exclusive so we can treat
- * it as a write lock. */
- tdb->allrecord_lock.ltype = upgradable ? F_WRLCK : ltype;
- tdb->allrecord_lock.off = upgradable;
return 0;
}
tdb->allrecord_lock.count = 0;
tdb->allrecord_lock.ltype = 0;
+ tdb->header_uptodate = false;
hash_size = (1ULL << tdb->header.v.hash_bits);
enum tdb_lock_flags waitflag)
{
/* You're supposed to have a hash lock first! */
- if (!tdb_has_locks(tdb)) {
+ if (!(tdb->flags & TDB_NOLOCK) && !tdb_has_locks(tdb)) {
tdb->ecode = TDB_ERR_LOCK;
tdb->log(tdb, TDB_DEBUG_FATAL, tdb->log_priv,
"tdb_lock_free_list without lock!\n");
tdb->header_uptodate = false;
}
#endif
+
+void tdb_lock_init(struct tdb_context *tdb)
+{
+ tdb->num_lockrecs = 0;
+ tdb->lockrecs = NULL;
+ tdb->allrecord_lock.count = 0;
+}