diff --git a/src/osd_primary.cpp b/src/osd_primary.cpp index 71132c18..95d947c3 100644 --- a/src/osd_primary.cpp +++ b/src/osd_primary.cpp @@ -228,7 +228,7 @@ resume_1: resume_2: if (op_data->errors > 0) { - finish_op(cur_op, op_data->epipe > 0 ? -EPIPE : -EIO); + finish_op(cur_op, op_data->errcode); return; } cur_op->reply.rw.version = op_data->fact_ver; @@ -350,7 +350,7 @@ resume_2: resume_3: if (op_data->errors > 0) { - pg_cancel_write_queue(pg, cur_op, op_data->oid, op_data->epipe > 0 ? -EPIPE : -EIO); + pg_cancel_write_queue(pg, cur_op, op_data->oid, op_data->errcode); return; } // Check CAS version @@ -371,7 +371,7 @@ resume_4: resume_5: if (op_data->errors > 0) { - pg_cancel_write_queue(pg, cur_op, op_data->oid, op_data->epipe > 0 ? -EPIPE : -EIO); + pg_cancel_write_queue(pg, cur_op, op_data->oid, op_data->errcode); return; } // Remove version override diff --git a/src/osd_primary.h b/src/osd_primary.h index e645ee4f..ce667468 100644 --- a/src/osd_primary.h +++ b/src/osd_primary.h @@ -24,7 +24,7 @@ struct osd_primary_op_data_t uint64_t target_ver; uint64_t orig_ver = 0, fact_ver = 0; uint64_t scheme = 0; - int n_subops = 0, done = 0, errors = 0, epipe = 0; + int n_subops = 0, done = 0, errors = 0, errcode = 0; int degraded = 0, pg_size, pg_data_size; osd_rmw_stripe_t *stripes; osd_op_t *subops = NULL; diff --git a/src/osd_primary_chain.cpp b/src/osd_primary_chain.cpp index 74fb94d7..2ae51fdb 100644 --- a/src/osd_primary_chain.cpp +++ b/src/osd_primary_chain.cpp @@ -42,7 +42,7 @@ resume_4: { free(op_data->chain_reads); op_data->chain_reads = NULL; - finish_op(cur_op, op_data->epipe > 0 ? -EPIPE : -EIO); + finish_op(cur_op, op_data->errcode); return; } send_chained_read_results(pg, cur_op); diff --git a/src/osd_primary_subops.cpp b/src/osd_primary_subops.cpp index a384dac2..bba5d231 100644 --- a/src/osd_primary_subops.cpp +++ b/src/osd_primary_subops.cpp @@ -122,7 +122,7 @@ void osd_t::submit_primary_subops(int submit_type, uint64_t op_version, const ui zero_read = -1; osd_op_t *subops = new osd_op_t[n_subops]; op_data->fact_ver = 0; - op_data->done = op_data->errors = 0; + op_data->done = op_data->errors = op_data->errcode = 0; op_data->n_subops = n_subops; op_data->subops = subops; int sent = submit_primary_subop_batch(submit_type, op_data->oid.inode, op_version, op_data->stripes, osd_set, cur_op, 0, zero_read); @@ -341,9 +341,11 @@ void osd_t::handle_primary_subop(osd_op_t *subop, osd_op_t *cur_op) osd_op_names[opcode], subop->peer_fd, retval, expected ); } - if (retval == -EPIPE) + // Error priority: EIO > ENOSPC > EPIPE + if (op_data->errcode == 0 || retval == -EIO || + retval == -ENOSPC && op_data->errcode == -EPIPE) { - op_data->epipe++; + op_data->errcode = retval; } op_data->errors++; if (subop->peer_fd >= 0 && (opcode != OSD_OP_SEC_WRITE && opcode != OSD_OP_SEC_WRITE_STABLE || @@ -413,7 +415,8 @@ void osd_t::cancel_primary_write(osd_op_t *cur_op) // are sent to peer OSDs, so we can't just throw them away. // Mark them with an extra EPIPE. cur_op->op_data->errors++; - cur_op->op_data->epipe++; + if (cur_op->op_data->errcode == 0) + cur_op->op_data->errcode = -EPIPE; cur_op->op_data->done--; // Caution: `done` must be signed because may become -1 here } else @@ -465,7 +468,7 @@ void osd_t::submit_primary_del_batch(osd_op_t *cur_op, obj_ver_osd_t *chunks_to_ { osd_primary_op_data_t *op_data = cur_op->op_data; op_data->n_subops = chunks_to_delete_count; - op_data->done = op_data->errors = 0; + op_data->done = op_data->errors = op_data->errcode = 0; if (!op_data->n_subops) { return; @@ -528,7 +531,7 @@ int osd_t::submit_primary_sync_subops(osd_op_t *cur_op) osd_primary_op_data_t *op_data = cur_op->op_data; int n_osds = op_data->dirty_osd_count; osd_op_t *subops = new osd_op_t[n_osds]; - op_data->done = op_data->errors = 0; + op_data->done = op_data->errors = op_data->errcode = 0; op_data->n_subops = n_osds; op_data->subops = subops; std::map::iterator peer_it; @@ -584,7 +587,7 @@ void osd_t::submit_primary_stab_subops(osd_op_t *cur_op) osd_primary_op_data_t *op_data = cur_op->op_data; int n_osds = op_data->unstable_write_osds->size(); osd_op_t *subops = new osd_op_t[n_osds]; - op_data->done = op_data->errors = 0; + op_data->done = op_data->errors = op_data->errcode = 0; op_data->n_subops = n_osds; op_data->subops = subops; for (int i = 0; i < n_osds; i++) diff --git a/src/osd_primary_sync.cpp b/src/osd_primary_sync.cpp index b960456e..30a123d1 100644 --- a/src/osd_primary_sync.cpp +++ b/src/osd_primary_sync.cpp @@ -240,7 +240,7 @@ resume_8: } if (op_data->errors > 0) { - finish_op(cur_op, op_data->epipe > 0 ? -EPIPE : -EIO); + finish_op(cur_op, op_data->errcode); } else { diff --git a/src/osd_primary_write.cpp b/src/osd_primary_write.cpp index 50142eb1..1dcb9c49 100644 --- a/src/osd_primary_write.cpp +++ b/src/osd_primary_write.cpp @@ -93,7 +93,7 @@ resume_2: resume_3: if (op_data->errors > 0) { - pg_cancel_write_queue(pg, cur_op, op_data->oid, op_data->epipe > 0 ? -EPIPE : -EIO); + pg_cancel_write_queue(pg, cur_op, op_data->oid, op_data->errcode); return; } // Check CAS version @@ -178,7 +178,7 @@ resume_5: } if (op_data->errors > 0) { - pg_cancel_write_queue(pg, cur_op, op_data->oid, op_data->epipe > 0 ? -EPIPE : -EIO); + pg_cancel_write_queue(pg, cur_op, op_data->oid, op_data->errcode); return; } if (op_data->object_state) @@ -255,7 +255,7 @@ resume_8: resume_9: if (op_data->errors > 0) { - pg_cancel_write_queue(pg, cur_op, op_data->oid, op_data->epipe > 0 ? -EPIPE : -EIO); + pg_cancel_write_queue(pg, cur_op, op_data->oid, op_data->errcode); return; } } @@ -337,7 +337,7 @@ resume_7: op_data->unstable_write_osds = NULL; if (op_data->errors > 0) { - pg_cancel_write_queue(pg, cur_op, op_data->oid, op_data->epipe > 0 ? -EPIPE : -EIO); + pg_cancel_write_queue(pg, cur_op, op_data->oid, op_data->errcode); return false; } }