From: David Zafman Date: Tue, 18 Mar 2014 00:14:17 +0000 (-0700) Subject: osd: start_flush() should check for missing clones and return if requested X-Git-Tag: v0.80-rc1~93^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=38bcd3cf2e68a90d2ac7f885dfc9f97831240f4a;p=ceph.git osd: start_flush() should check for missing clones and return if requested Fixes: #7659 Signed-off-by: David Zafman --- diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index 8a822fdf065..b52cf443d41 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -3196,7 +3196,7 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector& ops) break; } if (oi.is_dirty()) { - result = start_flush(ctx, false); + result = start_flush(ctx, false, NULL); } else { result = 0; } @@ -3219,11 +3219,20 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector& ops) result = 0; break; } + hobject_t missing; if (oi.is_dirty()) { - result = start_flush(ctx, true); + result = start_flush(ctx, true, &missing); } else { result = 0; } + // Check special return value which has set missing_return + if (result == -ENOENT) { + dout(10) << __func__ << " CEPH_OSD_OP_CACHE_FLUSH got ENOENT" << dendl; + assert(!missing.is_min()); + wait_for_unreadable_object(missing, ctx->op); + // Error code which is used elsewhere when wait_for_unreadable_object() is used + result = -EAGAIN; + } } break; @@ -5868,7 +5877,7 @@ struct C_Flush : public Context { } }; -int ReplicatedPG::start_flush(OpContext *ctx, bool blocking) +int ReplicatedPG::start_flush(OpContext *ctx, bool blocking, hobject_t *pmissing) { const object_info_t& oi = ctx->obc->obs.oi; const hobject_t& soid = oi.soid; @@ -5889,6 +5898,12 @@ int ReplicatedPG::start_flush(OpContext *ctx, bool blocking) hobject_t next = soid; next.snap = *p; assert(next.snap < soid.snap); + if (pg_log.get_missing().is_missing(next)) { + dout(10) << __func__ << " missing clone is " << next << dendl; + if (pmissing) + *pmissing = next; + return -ENOENT; + } ObjectContextRef older_obc = get_object_context(next, false); if (older_obc) { dout(20) << __func__ << " next oldest clone is " << older_obc->obs.oi @@ -10760,7 +10775,7 @@ bool ReplicatedPG::agent_maybe_flush(ObjectContextRef& obc) ctx->at_version = get_next_version(); ctx->on_finish = new C_AgentFlushStartStop(this, obc->obs.oi.soid); - int result = start_flush(ctx, false); + int result = start_flush(ctx, false, NULL); if (result != -EINPROGRESS) { dout(10) << __func__ << " start_flush() failed " << obc->obs.oi << " with " << result << dendl; diff --git a/src/osd/ReplicatedPG.h b/src/osd/ReplicatedPG.h index 3b8dea67bec..b254f5bd3d9 100644 --- a/src/osd/ReplicatedPG.h +++ b/src/osd/ReplicatedPG.h @@ -1181,7 +1181,7 @@ protected: // -- flush -- map flush_ops; - int start_flush(OpContext *ctx, bool blocking); + int start_flush(OpContext *ctx, bool blocking, hobject_t *pmissing); void finish_flush(hobject_t oid, ceph_tid_t tid, int r); int try_flush_mark_clean(FlushOpRef fop); void cancel_flush(FlushOpRef fop, bool requeue);