]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: start_flush() should check for missing clones and return if requested
authorDavid Zafman <david.zafman@inktank.com>
Tue, 18 Mar 2014 00:14:17 +0000 (17:14 -0700)
committerDavid Zafman <david.zafman@inktank.com>
Tue, 25 Mar 2014 18:11:57 +0000 (11:11 -0700)
Fixes: #7659
Signed-off-by: David Zafman <david.zafman@inktank.com>
src/osd/ReplicatedPG.cc
src/osd/ReplicatedPG.h

index 8a822fdf065ffe38c57f9f9db7a78ad25dc22279..b52cf443d41eab9de47819ddde61a7de2f769079 100644 (file)
@@ -3196,7 +3196,7 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& 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<OSDOp>& 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;
index 3b8dea67becdff8e0cacbc65bad768e60ae664ce..b254f5bd3d991e6369d254766bcbc57f09acab0a 100644 (file)
@@ -1181,7 +1181,7 @@ protected:
   // -- flush --
   map<hobject_t, FlushOpRef> 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);