From: Sage Weil Date: Thu, 29 Jan 2015 19:27:19 +0000 (-0800) Subject: osd: preserved extra_reqids on promote, flush X-Git-Tag: v0.93~146^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=eefdb32cf5dfea80ba1aa9da59e79df2b928b1a0;p=ceph.git osd: preserved extra_reqids on promote, flush This fixes idempotency for operations across caching changes (promote, flush and cache mode changes). Fixes: #8935 Signed-off-by: Sage Weil --- diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index e0e1830aa8ca..5f74fe57f550 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -1451,6 +1451,11 @@ void ReplicatedPG::do_op(OpRequestRef& op) // dup/replay? if (op->may_write() || op->may_cache()) { + // warning: we will get back *a* request for this reqid, but not + // necessarily the most recent. this happens with flush and + // promote ops, but we can't possible have both in our log where + // the original request is still not stable on disk, so for our + // purposes here it doesn't matter which one we get. const pg_log_entry_t *entry = pg_log.get_log().get_request(m->get_reqid()); if (entry) { const eversion_t& oldv = entry->version; @@ -5923,6 +5928,10 @@ void ReplicatedPG::finish_ctx(OpContext *ctx, int log_op_type, bool maintain_ssc } ctx->log.back().mod_desc.claim(ctx->mod_desc); + if (!ctx->extra_reqids.empty()) { + dout(20) << __func__ << " extra_reqids " << ctx->extra_reqids << dendl; + ctx->log.back().extra_reqids.swap(ctx->extra_reqids); + } // apply new object state. ctx->obc->obs = ctx->new_obs; @@ -6169,12 +6178,20 @@ int ReplicatedPG::fill_in_copy_get( } } + if (cursor.is_complete()) { + // include reqids only in the final step. this is a bit fragile + // but it works... + pg_log.get_log().get_object_reqids(ctx->obc->obs.oi.soid, 10, &reply_obj.reqids); + dout(20) << " got reqids" << dendl; + } + dout(20) << " cursor.is_complete=" << cursor.is_complete() << " " << out_attrs.size() << " attrs" << " " << bl.length() << " bytes" << " " << reply_obj.omap_header.length() << " omap header bytes" << " " << reply_obj.omap_data.length() << " omap data bytes in " << omap_keys << " keys" + << " " << reply_obj.reqids.size() << " reqids" << dendl; reply_obj.cursor = cursor; if (!async_read_started) { @@ -6264,6 +6281,7 @@ void ReplicatedPG::_copy_some(ObjectContextRef obc, CopyOpRef cop) &cop->results.flags, &cop->results.source_data_digest, &cop->results.source_omap_digest, + &cop->results.reqids, &cop->rval); C_Copyfrom *fin = new C_Copyfrom(this, obc->obs.oi.soid, @@ -6561,6 +6579,8 @@ void ReplicatedPG::finish_copyfrom(OpContext *ctx) obs.oi.set_data_digest(cb->results->data_digest); obs.oi.set_omap_digest(cb->results->omap_digest); + ctx->extra_reqids = cb->results->reqids; + // cache: clear whiteout? if (obs.oi.is_whiteout()) { dout(10) << __func__ << " clearing whiteout on " << obs.oi.soid << dendl; @@ -6681,6 +6701,8 @@ void ReplicatedPG::finish_promote(int r, CopyResults *results, ++tctx->delta_stats.num_object_clones; tctx->new_obs.exists = true; + tctx->extra_reqids = results->reqids; + if (whiteout) { // create a whiteout tctx->op_t->touch(soid); diff --git a/src/osd/ReplicatedPG.h b/src/osd/ReplicatedPG.h index 5ece59501684..44bf13e50856 100644 --- a/src/osd/ReplicatedPG.h +++ b/src/osd/ReplicatedPG.h @@ -126,6 +126,7 @@ public: uint32_t flags; // object_copy_data_t::FLAG_* uint32_t source_data_digest, source_omap_digest; uint32_t data_digest, omap_digest; + vector reqids; bool is_data_digest() { return flags & object_copy_data_t::FLAG_DATA_DIGEST; } @@ -531,6 +532,8 @@ public: int num_read; ///< count read ops int num_write; ///< count update ops + vector extra_reqids; + CopyFromCallback *copy_cb; hobject_t new_temp_oid, discard_temp_oid; ///< temp objects we should start/stop tracking diff --git a/src/osdc/Objecter.h b/src/osdc/Objecter.h index fb3aa392f956..ff7cb891f72a 100644 --- a/src/osdc/Objecter.h +++ b/src/osdc/Objecter.h @@ -625,6 +625,7 @@ struct ObjectOperation { uint32_t *out_flags; uint32_t *out_data_digest; uint32_t *out_omap_digest; + vector *out_reqids; int *prval; C_ObjectOperation_copyget(object_copy_cursor_t *c, uint64_t *s, @@ -637,13 +638,14 @@ struct ObjectOperation { uint32_t *flags, uint32_t *dd, uint32_t *od, + vector *oreqids, int *r) : cursor(c), out_size(s), out_mtime(m), out_attrs(a), out_data(d), out_omap_header(oh), out_omap_data(o), out_snaps(osnaps), out_snap_seq(osnap_seq), out_flags(flags), out_data_digest(dd), out_omap_digest(od), - prval(r) {} + out_reqids(oreqids), prval(r) {} void finish(int r) { if (r < 0) return; @@ -673,6 +675,8 @@ struct ObjectOperation { *out_data_digest = copy_reply.data_digest; if (out_omap_digest) *out_omap_digest = copy_reply.omap_digest; + if (out_reqids) + *out_reqids = copy_reply.reqids; *cursor = copy_reply.cursor; } catch (buffer::error& e) { if (prval) @@ -694,6 +698,7 @@ struct ObjectOperation { uint32_t *out_flags, uint32_t *out_data_digest, uint32_t *out_omap_digest, + vector *out_reqids, int *prval) { OSDOp& osd_op = add_op(CEPH_OSD_OP_COPY_GET); osd_op.op.copy_get.max = max; @@ -706,7 +711,7 @@ struct ObjectOperation { out_attrs, out_data, out_omap_header, out_omap_data, out_snaps, out_snap_seq, out_flags, out_data_digest, out_omap_digest, - prval); + out_reqids, prval); out_bl[p] = &h->bl; out_handler[p] = h; }