diff options
author | Sage Weil <sage@inktank.com> | 2013-08-24 21:58:11 -0700 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-08-27 15:42:44 -0700 |
commit | bb299fa4f3db2472ffd74d399b5f211a95588b6e (patch) | |
tree | 1d71cafa736768533431d03eeeef5f69953e47a9 | |
parent | 975de4e901d9830b458d043e68a44d9d1275fbc0 (diff) | |
download | ceph-bb299fa4f3db2472ffd74d399b5f211a95588b6e.tar.gz |
osd/ReplicatedPG: factor {execute,reply}_ctx() out of do_op()
Separate the processing of an OpContext from the preamble and
allocation, so that we can delay the execution for some ops (like the
COPYFROM operation we're about to add).
Signed-off-by: Sage Weil <sage@inktank.com>
-rw-r--r-- | src/osd/ReplicatedPG.cc | 78 | ||||
-rw-r--r-- | src/osd/ReplicatedPG.h | 3 |
2 files changed, 55 insertions, 26 deletions
diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index 2ebd15765f9..0f4965f10d0 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -877,41 +877,39 @@ void ReplicatedPG::do_op(OpRequestRef op) op->mark_started(); - const hobject_t& soid = obc->obs.oi.soid; OpContext *ctx = new OpContext(op, m->get_reqid(), m->ops, &obc->obs, obc->ssc, this); ctx->obc = obc; ctx->src_obc = src_obc; - if (op->may_write()) { - // snap - if (pool.info.is_pool_snaps_mode()) { - // use pool's snapc - ctx->snapc = pool.snapc; - } else { - // client specified snapc - ctx->snapc.seq = m->get_snap_seq(); - ctx->snapc.snaps = m->get_snaps(); - } - if ((m->get_flags() & CEPH_OSD_FLAG_ORDERSNAP) && - ctx->snapc.seq < obc->ssc->snapset.seq) { - dout(10) << " ORDERSNAP flag set and snapc seq " << ctx->snapc.seq - << " < snapset seq " << obc->ssc->snapset.seq - << " on " << soid << dendl; - delete ctx; - src_obc.clear(); - osd->reply_op_error(op, -EOLDSNAPC); - return; - } + execute_ctx(ctx); +} + +void ReplicatedPG::execute_ctx(OpContext *ctx) +{ + dout(10) << __func__ << " " << ctx << dendl; + OpRequestRef op = ctx->op; + MOSDOp *m = static_cast<MOSDOp*>(op->request); + ObjectContextRef obc = ctx->obc; + const hobject_t& soid = obc->obs.oi.soid; + map<hobject_t,ObjectContextRef>& src_obc = ctx->src_obc; + + // this method must be idempotent since we may call it several times + // before we finally apply the resulting transaction. + ctx->op_t = ObjectStore::Transaction(); + ctx->local_t = ObjectStore::Transaction(); + // dup/replay? + if (op->may_write()) { eversion_t oldv = pg_log.get_log().get_request_version(ctx->reqid); if (oldv != eversion_t()) { dout(3) << "do_op dup " << ctx->reqid << " was " << oldv << dendl; - delete ctx; if (already_complete(oldv)) { - osd->reply_op_error(op, 0, oldv); + reply_ctx(ctx, 0, oldv); } else { + delete ctx; + if (m->wants_ack()) { if (already_ack(oldv)) { MOSDOpReply *reply = new MOSDOpReply(m, 0, get_osdmap()->get_epoch(), 0); @@ -931,6 +929,24 @@ void ReplicatedPG::do_op(OpRequestRef op) op->mark_started(); + // snap + if (pool.info.is_pool_snaps_mode()) { + // use pool's snapc + ctx->snapc = pool.snapc; + } else { + // client specified snapc + ctx->snapc.seq = m->get_snap_seq(); + ctx->snapc.snaps = m->get_snaps(); + } + if ((m->get_flags() & CEPH_OSD_FLAG_ORDERSNAP) && + ctx->snapc.seq < obc->ssc->snapset.seq) { + dout(10) << " ORDERSNAP flag set and snapc seq " << ctx->snapc.seq + << " < snapset seq " << obc->ssc->snapset.seq + << " on " << obc->obs.oi.soid << dendl; + reply_ctx(ctx, -EOLDSNAPC); + return; + } + // version ctx->at_version = pg_log.get_head(); @@ -940,7 +956,7 @@ void ReplicatedPG::do_op(OpRequestRef op) assert(ctx->at_version > pg_log.get_head()); ctx->mtime = m->get_mtime(); - + dout(10) << "do_op " << soid << " " << ctx->ops << " ov " << obc->obs.oi.version << " av " << ctx->at_version << " snapc " << ctx->snapc @@ -990,8 +1006,7 @@ void ReplicatedPG::do_op(OpRequestRef op) // check for full if (ctx->delta_stats.num_bytes > 0 && pool.info.get_flags() & pg_pool_t::FLAG_FULL) { - delete ctx; - osd->reply_op_error(op, -ENOSPC); + reply_ctx(ctx, -ENOSPC); return; } @@ -1077,6 +1092,17 @@ void ReplicatedPG::do_op(OpRequestRef op) repop->put(); } +void ReplicatedPG::reply_ctx(OpContext *ctx, int r) +{ + osd->reply_op_error(ctx->op, -ENOSPC); + delete ctx; +} + +void ReplicatedPG::reply_ctx(OpContext *ctx, int r, eversion_t v) +{ + osd->reply_op_error(ctx->op, -ENOSPC, v); + delete ctx; +} void ReplicatedPG::log_op_stats(OpContext *ctx) { diff --git a/src/osd/ReplicatedPG.h b/src/osd/ReplicatedPG.h index 0fbe5afd9ca..9f076ecab24 100644 --- a/src/osd/ReplicatedPG.h +++ b/src/osd/ReplicatedPG.h @@ -575,6 +575,9 @@ protected: void _make_clone(ObjectStore::Transaction& t, const hobject_t& head, const hobject_t& coid, object_info_t *poi); + void execute_ctx(OpContext *ctx); + void reply_ctx(OpContext *ctx, int err); + void reply_ctx(OpContext *ctx, int err, eversion_t v); void make_writeable(OpContext *ctx); void log_op_stats(OpContext *ctx); |