Commit 06a5b1a8 authored by Rusty Russell's avatar Rusty Russell

tdb2: fix coalesce race #3

When we're coalescing, we need to drop the lock on the current free list, as
we've enlarged the block and it may now belong in a different list.

Unfortunately (as shown by repeated tdbtorture -n 8) another coalescing run
can do the coalescing while we've dropped the lock.  So for this case, we
use the TDB_COALESCING_MAGIC flag so it doesn't look free.
parent 56ea2c52
...@@ -347,7 +347,17 @@ static int coalesce(struct tdb_context *tdb, ...@@ -347,7 +347,17 @@ static int coalesce(struct tdb_context *tdb,
if (remove_from_list(tdb, b_off, off, r) == -1) if (remove_from_list(tdb, b_off, off, r) == -1)
goto err; goto err;
/* We have to drop this to avoid deadlocks. */ r = tdb_access_write(tdb, off, sizeof(*r), true);
if (!r)
goto err;
/* We have to drop this to avoid deadlocks, so make sure record
* doesn't get coalesced by someone else! */
r->magic_and_meta = TDB_COALESCING_MAGIC | zone_bits;
r->data_len = end - off - sizeof(struct tdb_used_record);
if (tdb_access_commit(tdb, r) != 0)
goto err;
tdb_unlock_free_bucket(tdb, b_off); tdb_unlock_free_bucket(tdb, b_off);
if (add_free_record(tdb, zone_bits, off, end - off) == -1) if (add_free_record(tdb, zone_bits, off, end - off) == -1)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment