Records themselves get (read) locked by the traversal code against delete.
Interestingly, this locking isn't done when the allrecord lock has been
taken, though the allrecord lock until recently didn't cover the actual
records (it now goes to end of file).
The write record lock, grabbed by the delete code, is not suppressed by
the allrecord lock, which causes us to punch a hole in that lock when we
release the write record lock. Make this consistent: *no* record locks
of any kind when the allrecord lock is taken.
for (i = &tdb->travlocks; i; i = i->next)
if (i->off == off)
return -1;
+ if (tdb->allrecord_lock.count) {
+ if (tdb->allrecord_lock.ltype == F_WRLCK) {
+ return 0;
+ }
+ return -1;
+ }
return tdb->methods->brlock(tdb, F_WRLCK, off, 1, TDB_LOCK_NOWAIT|TDB_LOCK_PROBE);
}
int tdb_write_unlock_record(struct tdb_context *tdb, tdb_off_t off)
{
+ if (tdb->allrecord_lock.count) {
+ return 0;
+ }
return tdb->methods->brunlock(tdb, F_WRLCK, off, 1);
}