Do not block writes on previous writes
This commit is contained in:
@@ -96,30 +96,21 @@ void blockstore_impl_t::loop()
|
|||||||
{
|
{
|
||||||
// try to submit ops
|
// try to submit ops
|
||||||
unsigned initial_ring_space = ringloop->space_left();
|
unsigned initial_ring_space = ringloop->space_left();
|
||||||
// has_writes == 0 - no writes before the current queue item
|
int op_idx = 0, new_idx = 0;
|
||||||
// has_writes == 1 - some writes in progress
|
|
||||||
// has_writes == 2 - tried to submit some writes, but failed
|
|
||||||
int has_writes = 0, op_idx = 0, new_idx = 0;
|
|
||||||
for (; op_idx < submit_queue.size(); op_idx++, new_idx++)
|
for (; op_idx < submit_queue.size(); op_idx++, new_idx++)
|
||||||
{
|
{
|
||||||
auto op = submit_queue[op_idx];
|
auto op = submit_queue[op_idx];
|
||||||
submit_queue[new_idx] = op;
|
submit_queue[new_idx] = op;
|
||||||
// FIXME: This needs some simplification
|
|
||||||
// Writes should not block reads if the ring is not full and reads don't depend on them
|
|
||||||
// In all other cases we should stop submission
|
|
||||||
if (PRIV(op)->wait_for)
|
if (PRIV(op)->wait_for)
|
||||||
{
|
{
|
||||||
check_wait(op);
|
check_wait(op);
|
||||||
if (PRIV(op)->wait_for == WAIT_SQE)
|
if (PRIV(op)->wait_for == WAIT_SQE)
|
||||||
{
|
{
|
||||||
|
// ring is full, stop submission
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (PRIV(op)->wait_for)
|
else if (PRIV(op)->wait_for)
|
||||||
{
|
{
|
||||||
if (op->opcode == BS_OP_WRITE || op->opcode == BS_OP_WRITE_STABLE || op->opcode == BS_OP_DELETE)
|
|
||||||
{
|
|
||||||
has_writes = 2;
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -134,19 +125,11 @@ void blockstore_impl_t::loop()
|
|||||||
}
|
}
|
||||||
else if (op->opcode == BS_OP_WRITE || op->opcode == BS_OP_WRITE_STABLE || op->opcode == BS_OP_DELETE)
|
else if (op->opcode == BS_OP_WRITE || op->opcode == BS_OP_WRITE_STABLE || op->opcode == BS_OP_DELETE)
|
||||||
{
|
{
|
||||||
if (has_writes == 2)
|
|
||||||
{
|
|
||||||
// Some writes already could not be submitted
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
wr_st = dequeue_write(op);
|
wr_st = dequeue_write(op);
|
||||||
has_writes = wr_st > 0 ? 1 : 2;
|
|
||||||
}
|
}
|
||||||
else if (op->opcode == BS_OP_SYNC)
|
else if (op->opcode == BS_OP_SYNC)
|
||||||
{
|
{
|
||||||
// sync only completed writes?
|
// syncs only completed writes, so doesn't have to be blocked by anything
|
||||||
// wait for the data device fsync to complete, then submit journal writes for big writes
|
|
||||||
// then submit an fsync operation
|
|
||||||
wr_st = continue_sync(op);
|
wr_st = continue_sync(op);
|
||||||
}
|
}
|
||||||
else if (op->opcode == BS_OP_STABLE || op->opcode == BS_OP_ROLLBACK)
|
else if (op->opcode == BS_OP_STABLE || op->opcode == BS_OP_ROLLBACK)
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ int blockstore_impl_t::do_sync(blockstore_op_t *op, int base_state)
|
|||||||
}
|
}
|
||||||
if (dsk.disable_journal_fsync && dsk.disable_meta_fsync || !unsynced_big_write_count && !unsynced_small_write_count)
|
if (dsk.disable_journal_fsync && dsk.disable_meta_fsync || !unsynced_big_write_count && !unsynced_small_write_count)
|
||||||
{
|
{
|
||||||
// We can return immediately because sync is only dequeued after all previous writes
|
// We can return immediately because sync only syncs previous writes
|
||||||
unsynced_big_write_count = unsynced_small_write_count = 0;
|
unsynced_big_write_count = unsynced_small_write_count = 0;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user