Correct reenterability fix (now verified with a test)
It's rather funny but 0.5.12 has to be re-published again
This commit is contained in:
+38
-28
@@ -10,7 +10,7 @@
|
||||
#define PART_ERROR 4
|
||||
#define CACHE_DIRTY 1
|
||||
#define CACHE_FLUSHING 2
|
||||
#define CACHE_REPEATING 4
|
||||
#define CACHE_REPEATING 3
|
||||
#define OP_FLUSH_BUFFER 2
|
||||
|
||||
cluster_client_t::cluster_client_t(ring_loop_t *ringloop, timerfd_manager_t *tfd, json11::Json & config)
|
||||
@@ -36,10 +36,10 @@ cluster_client_t::cluster_client_t(ring_loop_t *ringloop, timerfd_manager_t *tfd
|
||||
for (auto & wr: dirty_buffers)
|
||||
{
|
||||
if (affects_osd(wr.first.inode, wr.first.stripe, wr.second.len, peer_osd) &&
|
||||
!(wr.second.state & CACHE_REPEATING))
|
||||
wr.second.state != CACHE_REPEATING)
|
||||
{
|
||||
// FIXME: Flush in larger parts
|
||||
flush_buffer(wr.first, wr.second);
|
||||
flush_buffer(wr.first, &wr.second);
|
||||
}
|
||||
}
|
||||
continue_ops();
|
||||
@@ -103,21 +103,22 @@ void cluster_client_t::continue_ops(bool up_retry)
|
||||
}
|
||||
restart:
|
||||
continuing_ops = 1;
|
||||
op_queue_pos = 0;
|
||||
bool has_flushes = false, has_writes = false;
|
||||
int j = 0;
|
||||
for (int i = 0; i < op_queue.size(); i++)
|
||||
while (op_queue_pos < op_queue.size())
|
||||
{
|
||||
bool rm = false, is_flush = op_queue[i]->flags & OP_FLUSH_BUFFER;
|
||||
auto opcode = op_queue[i]->opcode;
|
||||
if (!op_queue[i]->up_wait || up_retry)
|
||||
auto op = op_queue[op_queue_pos];
|
||||
bool rm = false, is_flush = op->flags & OP_FLUSH_BUFFER;
|
||||
auto opcode = op->opcode;
|
||||
if (!op->up_wait || up_retry)
|
||||
{
|
||||
op_queue[i]->up_wait = false;
|
||||
op->up_wait = false;
|
||||
if (opcode == OSD_OP_READ || opcode == OSD_OP_WRITE)
|
||||
{
|
||||
if (is_flush || !has_flushes)
|
||||
{
|
||||
// Regular writes can't proceed before buffer flushes
|
||||
rm = continue_rw(op_queue[i]);
|
||||
rm = continue_rw(op);
|
||||
}
|
||||
}
|
||||
else if (opcode == OSD_OP_SYNC)
|
||||
@@ -125,7 +126,7 @@ restart:
|
||||
if (!has_writes)
|
||||
{
|
||||
// SYNC can't proceed before previous writes
|
||||
rm = continue_sync(op_queue[i]);
|
||||
rm = continue_sync(op);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -143,20 +144,20 @@ restart:
|
||||
// ...so dirty_writes can't contain anything newer than SYNC
|
||||
has_flushes = has_writes || !rm;
|
||||
}
|
||||
if (!rm)
|
||||
if (rm)
|
||||
{
|
||||
op_queue[j++] = op_queue[i];
|
||||
op_queue.erase(op_queue.begin()+op_queue_pos, op_queue.begin()+op_queue_pos+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
op_queue_pos++;
|
||||
}
|
||||
if (continuing_ops == 2)
|
||||
{
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
op_queue.resize(j);
|
||||
if (continuing_ops == 2)
|
||||
{
|
||||
goto restart;
|
||||
}
|
||||
else
|
||||
{
|
||||
continuing_ops = 0;
|
||||
}
|
||||
continuing_ops = 0;
|
||||
}
|
||||
|
||||
static uint32_t is_power_of_two(uint64_t value)
|
||||
@@ -433,21 +434,30 @@ void cluster_client_t::copy_write(cluster_op_t *op, std::map<object_id, cluster_
|
||||
}
|
||||
}
|
||||
|
||||
void cluster_client_t::flush_buffer(const object_id & oid, cluster_buffer_t & wr)
|
||||
void cluster_client_t::flush_buffer(const object_id & oid, cluster_buffer_t *wr)
|
||||
{
|
||||
wr.state = CACHE_DIRTY | CACHE_REPEATING;
|
||||
wr->state = CACHE_REPEATING;
|
||||
cluster_op_t *op = new cluster_op_t;
|
||||
op->flags = OP_FLUSH_BUFFER;
|
||||
op->opcode = OSD_OP_WRITE;
|
||||
op->inode = oid.inode;
|
||||
op->offset = oid.stripe;
|
||||
op->len = wr.len;
|
||||
op->iov.push_back(wr.buf, wr.len);
|
||||
op->callback = [](cluster_op_t* op)
|
||||
op->len = wr->len;
|
||||
op->iov.push_back(wr->buf, wr->len);
|
||||
op->callback = [wr](cluster_op_t* op)
|
||||
{
|
||||
if (wr->state == CACHE_REPEATING)
|
||||
{
|
||||
wr->state = CACHE_DIRTY;
|
||||
}
|
||||
delete op;
|
||||
};
|
||||
op_queue.push_front(op);
|
||||
op_queue.insert(op_queue.begin(), op);
|
||||
if (continuing_ops)
|
||||
{
|
||||
continuing_ops = 2;
|
||||
op_queue_pos++;
|
||||
}
|
||||
}
|
||||
|
||||
int cluster_client_t::continue_rw(cluster_op_t *op)
|
||||
|
||||
Reference in New Issue
Block a user