public:
MOSDOpReply()
: Message(CEPH_MSG_OSD_OPREPLY, HEAD_VERSION, COMPAT_VERSION) { }
- MOSDOpReply(MOSDOp *req, int r, epoch_t e, int acktype)
+ MOSDOpReply(MOSDOp *req, int r, epoch_t e, int acktype, bool ignore_out_data)
: Message(CEPH_MSG_OSD_OPREPLY, HEAD_VERSION, COMPAT_VERSION) {
set_tid(req->get_tid());
ops = req->ops;
user_version = 0;
retry_attempt = req->get_retry_attempt();
- // zero out ops payload_len
- for (unsigned i = 0; i < ops.size(); i++)
+ // zero out ops payload_len and possibly out data
+ for (unsigned i = 0; i < ops.size(); i++) {
ops[i].op.payload_len = 0;
+ if (ignore_out_data)
+ ops[i].outdata.clear();
+ }
}
private:
~MOSDOpReply() {}
// reply
MOSDOpReply *reply = new MOSDOpReply(m, 0, get_osdmap()->get_epoch(),
- CEPH_OSD_FLAG_ACK | CEPH_OSD_FLAG_ONDISK);
+ CEPH_OSD_FLAG_ACK | CEPH_OSD_FLAG_ONDISK,
+ false);
reply->claim_op_out_data(ops);
reply->set_result(result);
reply->set_reply_versions(info.last_update, info.last_user_version);
MOSDOp *m = static_cast<MOSDOp*>(op->get_req());
int flags = m->get_flags() & (CEPH_OSD_FLAG_ACK|CEPH_OSD_FLAG_ONDISK);
MOSDOpReply *reply = new MOSDOpReply(m, -ENOENT,
- get_osdmap()->get_epoch(), flags);
+ get_osdmap()->get_epoch(), flags, false);
request_redirect_t redir(m->get_object_locator(), pool.info.tier_of);
reply->set_redirect(redir);
dout(10) << "sending redirect to pool " << pool.info.tier_of << " for op "
if (m->wants_ack()) {
if (already_ack(oldv)) {
- MOSDOpReply *reply = new MOSDOpReply(m, 0, get_osdmap()->get_epoch(), 0);
+ MOSDOpReply *reply = new MOSDOpReply(m, 0, get_osdmap()->get_epoch(), 0, false);
reply->add_flags(CEPH_OSD_FLAG_ACK);
reply->set_reply_versions(oldv, entry->user_version);
osd->send_message_osd_client(reply, m->get_connection());
return;
}
+ bool successful_write = !ctx->op_t->empty() && ctx->modify && result >= 0;
// prepare the reply
- ctx->reply = new MOSDOpReply(m, 0, get_osdmap()->get_epoch(), 0);
+ ctx->reply = new MOSDOpReply(m, 0, get_osdmap()->get_epoch(), 0,
+ successful_write);
// Write operations aren't allowed to return a data payload because
// we can't do so reliably. If the client has to resend the request
// possible to construct an operation that does a read, does a guard
// check (e.g., CMPXATTR), and then a write. Then we either succeed
// with the write, or return a CMPXATTR and the read value.
- if (!((ctx->op_t->empty() && !ctx->modify) || result < 0)) {
+ if (successful_write) {
// write. normalize the result code.
- if (result > 0) {
- dout(20) << " zeroing write result code " << result << dendl;
- result = 0;
- }
+ dout(20) << " zeroing write result code " << result << dendl;
+ result = 0;
}
ctx->reply->set_result(result);
if (reply)
repop->ctx->reply = NULL;
else {
- reply = new MOSDOpReply(m, 0, get_osdmap()->get_epoch(), 0);
+ reply = new MOSDOpReply(m, 0, get_osdmap()->get_epoch(), 0, true);
reply->set_reply_versions(repop->ctx->at_version,
repop->ctx->user_at_version);
}
i != waiting_for_ack[repop->v].end();
++i) {
MOSDOp *m = (MOSDOp*)(*i)->get_req();
- MOSDOpReply *reply = new MOSDOpReply(m, 0, get_osdmap()->get_epoch(), 0);
+ MOSDOpReply *reply = new MOSDOpReply(m, 0, get_osdmap()->get_epoch(), 0, true);
reply->set_reply_versions(repop->ctx->at_version,
repop->ctx->user_at_version);
reply->add_flags(CEPH_OSD_FLAG_ACK);
if (reply)
repop->ctx->reply = NULL;
else {
- reply = new MOSDOpReply(m, 0, get_osdmap()->get_epoch(), 0);
+ reply = new MOSDOpReply(m, 0, get_osdmap()->get_epoch(), 0, true);
reply->set_reply_versions(repop->ctx->at_version,
repop->ctx->user_at_version);
}