Fix incorrect deferred freeing of block used by a parallel read in the old store

This commit is contained in:
Vitaliy Filippov
2026-06-13 19:55:47 +03:00
parent 6901227390
commit 43aa4cfff6
2 changed files with 10 additions and 10 deletions
+1 -1
View File
@@ -96,7 +96,7 @@ struct blockstore_op_private_t
int op_state; int op_state;
// Read // Read
uint64_t clean_block_used; uint64_t clean_loc_used;
std::vector<copy_buffer_t> read_vec; std::vector<copy_buffer_t> read_vec;
// Sync, write // Sync, write
+9 -9
View File
@@ -134,7 +134,7 @@ int blockstore_impl_t::fulfill_read(blockstore_op_t *read_op,
// If we don't track it then we may IN THEORY read another object's data: // If we don't track it then we may IN THEORY read another object's data:
// submit read -> remove the object -> flush remove -> overwrite with another object -> finish read // submit read -> remove the object -> flush remove -> overwrite with another object -> finish read
// Very improbable, but possible // Very improbable, but possible
PRIV(read_op)->clean_block_used = 1; PRIV(read_op)->clean_loc_used = 1;
} }
rv.insert(rv.begin() + pos, el); rv.insert(rv.begin() + pos, el);
fulfilled += el.len; fulfilled += el.len;
@@ -376,7 +376,7 @@ bool blockstore_impl_t::read_checksum_block(blockstore_op_t *op, int rv_pos, uin
{ {
// Reads running parallel to flushes of the same clean block may read // Reads running parallel to flushes of the same clean block may read
// a mixture of old and new data. So we don't verify checksums for such blocks. // a mixture of old and new data. So we don't verify checksums for such blocks.
PRIV(op)->clean_block_used = 1; PRIV(op)->clean_loc_used = 1;
} }
return true; return true;
} }
@@ -402,7 +402,7 @@ int blockstore_impl_t::dequeue_read(blockstore_op_t *read_op)
} }
uint64_t fulfilled = 0; uint64_t fulfilled = 0;
PRIV(read_op)->pending_ops = 0; PRIV(read_op)->pending_ops = 0;
PRIV(read_op)->clean_block_used = 0; PRIV(read_op)->clean_loc_used = 0;
auto & rv = PRIV(read_op)->read_vec; auto & rv = PRIV(read_op)->read_vec;
uint64_t result_version = 0; uint64_t result_version = 0;
if (dirty_found) if (dirty_found)
@@ -615,7 +615,7 @@ bool blockstore_impl_t::fulfill_clean_read(blockstore_op_t *read_op, uint64_t &
return false; return false;
} }
} }
PRIV(read_op)->clean_block_used = req > 0; PRIV(read_op)->clean_loc_used = req > 0;
} }
else if (from_journal) else if (from_journal)
{ {
@@ -679,13 +679,13 @@ bool blockstore_impl_t::fulfill_clean_read(blockstore_op_t *read_op, uint64_t &
} }
} }
// Increment reference counter if clean data is being read from the disk // Increment reference counter if clean data is being read from the disk
if (PRIV(read_op)->clean_block_used) if (PRIV(read_op)->clean_loc_used)
{ {
auto & uo = used_clean_objects[clean_loc]; auto & uo = used_clean_objects[clean_loc];
uo.refs++; uo.refs++;
if (dsk.csum_block_size && flusher->is_mutated(clean_loc)) if (dsk.csum_block_size && flusher->is_mutated(clean_loc))
uo.was_changed = true; uo.was_changed = true;
PRIV(read_op)->clean_block_used = clean_loc; PRIV(read_op)->clean_loc_used = clean_loc;
} }
return true; return true;
} }
@@ -944,10 +944,10 @@ void blockstore_impl_t::handle_read_event(ring_data_t *data, blockstore_op_t *op
meta_block = NULL; meta_block = NULL;
} }
} }
if (PRIV(op)->clean_block_used) if (PRIV(op)->clean_loc_used)
{ {
// Release clean data block // Release clean data block
auto uo_it = used_clean_objects.find(PRIV(op)->clean_block_used); auto uo_it = used_clean_objects.find(PRIV(op)->clean_loc_used);
if (uo_it != used_clean_objects.end()) if (uo_it != used_clean_objects.end())
{ {
uo_it->second.refs--; uo_it->second.refs--;
@@ -955,7 +955,7 @@ void blockstore_impl_t::handle_read_event(ring_data_t *data, blockstore_op_t *op
{ {
if (uo_it->second.was_freed) if (uo_it->second.was_freed)
{ {
data_alloc->set(PRIV(op)->clean_block_used, false); data_alloc->set(PRIV(op)->clean_loc_used / dsk.data_block_size, false);
} }
used_clean_objects.erase(uo_it); used_clean_objects.erase(uo_it);
} }