Fix assertion on region vs object liveliness during log read

This concerns an open issue from before the public release, which I
had not understood before and believe to have understood now.

With this code *) added to the test

@@ -5946,6 +5949,15 @@ t_cache(unsigned chksum)
	test_bocdone(fbo, TRUST_ME(hash), 1);
	fellow_cache_obj_deref(fc, fco);

+	// === max out region alloc
+	fbo = fellow_busy_obj_alloc(fc, &fco, &priv2, 1234).r.ptr;
+	CHECK_OBJ_NOTNULL(fbo, FELLOW_BUSY_MAGIC);
+	for (u = 0; u < FCO_MAX_REGIONS; u++)
+		AN(fellow_busy_region_alloc(fbo, 1234, INT8_MAX));
+
+	test_bocdone(fbo, TRUST_ME(hash), 1);
+	fellow_cache_obj_delete(fc, fco, hash);
+
	// === alloc space, dont use

we tripped here

   assert(flivs->oob || u == obj_alive);

with u == 1 and obj_alive == 0.

So the offset of a region from a dead object was not taken by a
subsequent allocation, which is fine, why should it be?

*) Note: The added test code is not correct yet, as it does not
   register the regions with the segment list, so obj_delete leaks.
parent c4927863
......@@ -5017,19 +5017,25 @@ fellow_logs_iter_block(const struct flics *flics, struct flivs *flivs,
case DLE_REG_ADD:
DLE_REG_FOREACH(e, off, sz) {
bit = off_bit(off);
// if object is not alive, this storage
// must also have been DEL'ed
/* mark any regions not already marked because
* they can not be valid for an earlier object.
*
* We can only assert that they were free if the
* object is alive, it is not, they might have
* been reused or not.
*/
u = bitf_set(flivs->bitf, bit);
FDBG(D_LOGS_ITER_BLOCK,
" u %u = bitf_set(%zu)", u, bit);
assert(flivs->oob || u == obj_alive);
// ^^^ XXX WIP bugs/20230106_iter_not_alive
// semantically a break, but sanity
// check the other regions too
if (! obj_alive)
continue;
AN(u);
switch (flics->ffd->phase) {
case FP_INIT:
case FP_OPEN:
......
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