From: Sage Weil Date: Thu, 12 Dec 2013 23:40:41 +0000 (-0800) Subject: osd/ReplicatedPG: fix user_version preservation for copy_from X-Git-Tag: v0.75~45^2~19 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=927b0e60c2ddf210faf13b198c98e11972805d28;p=ceph.git osd/ReplicatedPG: fix user_version preservation for copy_from In the process of fixing this for flush, we break promote, so we need to adjust them both here. Basic strategy: do not set user_modify, but handle the user_version explicitly in the callbacks. For copy_from, we don't have a clean way to pass the result through to finish_copyfrom in do_osd_ops; do so by putting it in user_at_version. (If we were to call finish_copyfrom directly from the callback this might be simpler, but let's not go there right now.) For promote, it is a trivial fix. Signed-off-by: Sage Weil --- diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index dbc172f298fd..64e354f176a1 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -119,6 +119,10 @@ public: results = results_.get<1>(); int r = results_.get<0>(); retval = r; + + // for finish_copyfrom + ctx->user_at_version = results->user_version; + if (r >= 0) { ctx->pg->execute_ctx(ctx); } @@ -1401,7 +1405,7 @@ void ReplicatedPG::promote_object(OpRequestRef op, ObjectContextRef obc) &obc, true, NULL); assert(r == 0); // a lookup that allows creates can't fail now } -dout(10) << __func__ << " " << obc->obs.oi.soid << dendl; + dout(10) << __func__ << " " << obc->obs.oi.soid << dendl; hobject_t temp_target = generate_temp_object(); PromoteCallback *cb = new PromoteCallback(op, obc, temp_target, this); @@ -1495,7 +1499,9 @@ void ReplicatedPG::execute_ctx(OpContext *ctx) << dendl; } - ctx->user_at_version = obc->obs.oi.user_version; + if (!ctx->user_at_version) + ctx->user_at_version = obc->obs.oi.user_version; + dout(30) << __func__ << " user_at_version " << ctx->user_at_version << dendl; // note my stats utime_t now = ceph_clock_now(cct); @@ -2604,6 +2610,7 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector& ops) case CEPH_OSD_OP_CACHE_FLUSH: case CEPH_OSD_OP_CACHE_TRY_FLUSH: case CEPH_OSD_OP_UNDIRTY: + case CEPH_OSD_OP_COPY_FROM: // we handle user_version update explicitly break; default: if (op.op & CEPH_OSD_OP_MODE_WR) @@ -4821,6 +4828,9 @@ void ReplicatedPG::finish_copyfrom(OpContext *ctx) ctx->op_t.swap(cb->results->final_tx); ctx->op_t.append(cb->results->final_tx); + // CopyFromCallback fills this in for us + obs.oi.user_version = ctx->user_at_version; + interval_set ch; if (obs.oi.size > 0) ch.insert(0, obs.oi.size); @@ -4840,7 +4850,8 @@ void ReplicatedPG::finish_promote(int r, OpRequestRef op, hobject_t& temp_obj) { const hobject_t& soid = obc->obs.oi.soid; - dout(10) << __func__ << " " << soid << " r=" << r << dendl; + dout(10) << __func__ << " " << soid << " r=" << r + << " uv" << results->user_version << dendl; bool whiteout = false; if (r == -ENOENT && @@ -4878,6 +4889,7 @@ void ReplicatedPG::finish_promote(int r, OpRequestRef op, // create a whiteout tctx->op_t.touch(coll, soid); tctx->new_obs.oi.set_flag(object_info_t::FLAG_WHITEOUT); + dout(20) << __func__ << " creating whiteout" << dendl; } else { tctx->op_t.swap(results->final_tx); if (results->started_temp_obj) { @@ -4886,7 +4898,7 @@ void ReplicatedPG::finish_promote(int r, OpRequestRef op, tctx->new_obs.oi.size = results->object_size; tctx->delta_stats.num_bytes += results->object_size; tctx->new_obs.oi.category = results->category; - tctx->user_at_version = results->user_version; + tctx->new_obs.oi.user_version = results->user_version; } repop->ondone = new C_KickBlockedObject(obc, this);