summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-08-24 21:58:11 -0700
committerSage Weil <sage@inktank.com>2013-08-30 16:57:25 -0700
commit8d74f417eac3cfcfb0b99fdf0734e210447798ae (patch)
treec04ddd588d4146505eb48a08a3959cad44fb0790
parentbc99437ef66982f99593660ae3c4606b488a59d2 (diff)
downloadceph-8d74f417eac3cfcfb0b99fdf0734e210447798ae.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.cc78
-rw-r--r--src/osd/ReplicatedPG.h3
2 files changed, 55 insertions, 26 deletions
diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc
index 234004341fd..7d0811c4d96 100644
--- a/src/osd/ReplicatedPG.cc
+++ b/src/osd/ReplicatedPG.cc
@@ -877,42 +877,40 @@ 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()) {
const pg_log_entry_t *entry = pg_log.get_log().get_request(ctx->reqid);
if (entry) {
const eversion_t& oldv = entry->version;
dout(3) << "do_op dup " << ctx->reqid << " was " << oldv << dendl;
- delete ctx;
if (already_complete(oldv)) {
- osd->reply_op_error(op, 0, oldv, entry->user_version);
+ reply_ctx(ctx, 0, oldv, entry->user_version);
} else {
+ delete ctx;
+
if (m->wants_ack()) {
if (already_ack(oldv)) {
MOSDOpReply *reply = new MOSDOpReply(m, 0, get_osdmap()->get_epoch(), 0);
@@ -932,6 +930,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();
@@ -941,7 +957,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
@@ -993,8 +1009,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;
}
@@ -1084,6 +1099,17 @@ void ReplicatedPG::do_op(OpRequestRef op)
repop->put();
}
+void ReplicatedPG::reply_ctx(OpContext *ctx, int r)
+{
+ osd->reply_op_error(ctx->op, r);
+ delete ctx;
+}
+
+void ReplicatedPG::reply_ctx(OpContext *ctx, int r, eversion_t v, version_t uv)
+{
+ osd->reply_op_error(ctx->op, r, v, uv);
+ delete ctx;
+}
void ReplicatedPG::log_op_stats(OpContext *ctx)
{
diff --git a/src/osd/ReplicatedPG.h b/src/osd/ReplicatedPG.h
index bce141834ca..5dc7d882a8b 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, version_t uv);
void make_writeable(OpContext *ctx);
void log_op_stats(OpContext *ctx);