From: David Disseldorp Date: Wed, 2 Aug 2017 19:09:03 +0000 (+0200) Subject: osd: move CMPEXT response munging into completion function X-Git-Tag: ses5-milestone10~4^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=a8ae498fc193e7fe085a7e54576cee7701ca0863;p=ceph.git osd: move CMPEXT response munging into completion function 6f860ff8da36bd74954b5982ce4cc1741b34bcfe added functionality to munge old (SES <= 4) cmpext requests and responses, to ensure that clients weren't affected by the API change. cmpext on EC support (04cf38cc159479417562da36848537ee99892d7d), added a cmpext asynchronous completion handler which broke response munging. This change reinstates cmpext response munging, ensuring that the munged request state is tracked through to the completion handler. (bsc#1047244). Signed-off-by: David Disseldorp --- diff --git a/src/osd/PrimaryLogPG.cc b/src/osd/PrimaryLogPG.cc index a6f638baa9f7..8b89f9bc1010 100644 --- a/src/osd/PrimaryLogPG.cc +++ b/src/osd/PrimaryLogPG.cc @@ -4680,14 +4680,16 @@ struct C_ExtentCmpRead : public Context { ceph_le64 read_length; bufferlist read_bl; Context *fill_extent_ctx; + bool munged; C_ExtentCmpRead(PrimaryLogPG *primary_log_pg, OSDOp &osd_op, boost::optional maybe_crc, uint64_t size, - OSDService *osd, hobject_t soid, __le32 flags) + OSDService *osd, hobject_t soid, __le32 flags, bool munged) : primary_log_pg(primary_log_pg), osd_op(osd_op), fill_extent_ctx(new FillInVerifyExtent(&read_length, &osd_op.rval, &read_bl, maybe_crc, size, - osd, soid, flags)) { + osd, soid, flags)), + munged(munged) { } ~C_ExtentCmpRead() override { delete fill_extent_ctx; @@ -4704,19 +4706,19 @@ struct C_ExtentCmpRead : public Context { fill_extent_ctx = nullptr; if (osd_op.rval >= 0) { - osd_op.rval = primary_log_pg->finish_extent_cmp(osd_op, read_bl); + osd_op.rval = primary_log_pg->finish_extent_cmp(osd_op, read_bl, munged); } } }; -int PrimaryLogPG::do_extent_cmp(OpContext *ctx, OSDOp& osd_op) +int PrimaryLogPG::do_extent_cmp(OpContext *ctx, OSDOp& osd_op, bool munged) { dout(20) << __func__ << dendl; ceph_osd_op& op = osd_op.op; if (!ctx->obs->exists || ctx->obs->oi.is_whiteout()) { dout(20) << __func__ << " object DNE" << dendl; - return finish_extent_cmp(osd_op, {}); + return finish_extent_cmp(osd_op, {}, munged); } else if (pool.info.require_rollback()) { // If there is a data digest and it is possible we are reading // entire object, pass the digest. @@ -4730,7 +4732,7 @@ int PrimaryLogPG::do_extent_cmp(OpContext *ctx, OSDOp& osd_op) // async read auto& soid = oi.soid; auto extent_cmp_ctx = new C_ExtentCmpRead(this, osd_op, maybe_crc, oi.size, - osd, soid, op.flags); + osd, soid, op.flags, munged); ctx->pending_async_reads.push_back({ {op.extent.offset, op.extent.length, op.flags}, {&extent_cmp_ctx->read_bl, extent_cmp_ctx}}); @@ -4757,15 +4759,21 @@ int PrimaryLogPG::do_extent_cmp(OpContext *ctx, OSDOp& osd_op) derr << __func__ << " failed " << result << dendl; return result; } - return finish_extent_cmp(osd_op, read_op.outdata); + return finish_extent_cmp(osd_op, read_op.outdata, munged); } -int PrimaryLogPG::finish_extent_cmp(OSDOp& osd_op, const bufferlist &read_bl) +int PrimaryLogPG::finish_extent_cmp(OSDOp& osd_op, const bufferlist &read_bl, bool munged) { for (uint64_t idx = 0; idx < osd_op.indata.length(); ++idx) { char read_byte = (idx < read_bl.length() ? read_bl[idx] : 0); if (osd_op.indata[idx] != read_byte) { - return (-MAX_ERRNO - idx); + if (munged) { + dout(10) << "munging mismatch: " << idx << dendl; + // SES < 5 mismatch returns -EILSEQ, with offset sent as response data + ::encode(idx, osd_op.outdata); + return -EILSEQ; + } + return (-MAX_ERRNO - idx); } } @@ -5106,13 +5114,7 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector& ops) op.extent.truncate_seq); if (op_finisher == nullptr) { - result = do_extent_cmp(ctx, osd_op); - if (cmpext_munged && (result <= -MAX_ERRNO)) { - dout(10) << "munging mismatch: " << (-result - MAX_ERRNO) << dendl; - // SES < 5 mismatch returns -EILSEQ, with offset sent as response data - ::encode(-result - MAX_ERRNO, osd_op.outdata); - result = -EILSEQ; - } + result = do_extent_cmp(ctx, osd_op, cmpext_munged); } else { result = op_finisher->execute(); } @@ -5141,11 +5143,6 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector& ops) break; case CEPH_OSD_OP_CHECKSUM: - derr << "CEPH_OSD_OP_CHECKSUM: datalen:" - << osd_op.indata.length() << " payloadlen:" - << op.payload_len << " sizeof(struct):" - << sizeof(op.checksum) << dendl; - ++ctx->num_read; { tracepoint(osd, do_osd_op_pre_checksum, soid.oid.name.c_str(), diff --git a/src/osd/PrimaryLogPG.h b/src/osd/PrimaryLogPG.h index a4d34d17141d..534c3488019e 100644 --- a/src/osd/PrimaryLogPG.h +++ b/src/osd/PrimaryLogPG.h @@ -1332,8 +1332,8 @@ protected: friend class C_ChecksumRead; - int do_extent_cmp(OpContext *ctx, OSDOp& osd_op); - int finish_extent_cmp(OSDOp& osd_op, const bufferlist &read_bl); + int do_extent_cmp(OpContext *ctx, OSDOp& osd_op, bool munged); + int finish_extent_cmp(OSDOp& osd_op, const bufferlist &read_bl, bool munged); friend class C_ExtentCmpRead;