Fix OSDs still crashing when the cluster is full with EC

ENOSPC handling was introduced in 1.6.0 but it was not complete; now it is

P.S: See also client_retry_enospc (true by default)
This commit is contained in:
Vitaliy Filippov
2024-12-26 01:56:33 +03:00
parent cef98052f5
commit 42eebfc1bd
2 changed files with 10 additions and 8 deletions
+2 -2
View File
@@ -744,7 +744,7 @@ void osd_t::submit_primary_rollback_subops(osd_op_t *cur_op, const uint64_t* osd
for (int role = 0; role < op_data->pg_size; role++)
{
if (osd_set[role] != 0 && !stripes[role].read_error &&
msgr.osd_peer_fds.find(osd_set[role]) != msgr.osd_peer_fds.end())
(osd_set[role] == this->osd_num || msgr.osd_peer_fds.find(osd_set[role]) != msgr.osd_peer_fds.end()))
{
n_subops++;
}
@@ -761,7 +761,7 @@ void osd_t::submit_primary_rollback_subops(osd_op_t *cur_op, const uint64_t* osd
for (int role = 0; role < op_data->pg_size; role++)
{
if (osd_set[role] != 0 && !stripes[role].read_error &&
msgr.osd_peer_fds.find(osd_set[role]) != msgr.osd_peer_fds.end())
(osd_set[role] == this->osd_num || msgr.osd_peer_fds.find(osd_set[role]) != msgr.osd_peer_fds.end()))
{
osd_op_t *subop = &op_data->subops[i];
op_data->unstable_writes[i] = (obj_ver_id){
+8 -6
View File
@@ -260,11 +260,6 @@ resume_4:
op_data->st = 4;
return;
resume_5:
if (op_data->scheme != POOL_SCHEME_REPLICATED)
{
// Remove version override just after the write, but before stabilizing
pg.ver_override.erase(op_data->oid);
}
if (op_data->errors > 0)
{
// Handle ENOSPC/EDOM/ERANGE/EIO. If some subops fail, but others succeed,
@@ -276,7 +271,7 @@ resume_5:
{
if (op_data->scheme != POOL_SCHEME_REPLICATED)
{
submit_primary_rollback_subops(cur_op, op_data->prev_set);
submit_primary_rollback_subops(cur_op, pg.cur_set.data());
resume_11:
op_data->st = 11;
return;
@@ -287,15 +282,22 @@ resume_12:
}
else
{
pg.ver_override.erase(op_data->oid);
mark_partial_write(pg, op_data->oid, op_data->object_state, op_data->stripes, true);
pg_cancel_write_queue(pg, cur_op, op_data->oid, op_data->errcode);
return;
}
}
pg.ver_override.erase(op_data->oid);
deref_object_state(pg, &op_data->object_state, true);
pg_cancel_write_queue(pg, cur_op, op_data->oid, op_data->errcode);
return;
}
if (op_data->scheme != POOL_SCHEME_REPLICATED)
{
// Remove version override just after the write, but before stabilizing
pg.ver_override.erase(op_data->oid);
}
if (op_data->object_state)
{
// We must forget the unclean state of the object before deleting it