]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: preserved extra_reqids on promote, flush
authorSage Weil <sage@redhat.com>
Thu, 29 Jan 2015 19:27:19 +0000 (11:27 -0800)
committerSage Weil <sage@redhat.com>
Thu, 29 Jan 2015 19:29:51 +0000 (11:29 -0800)
This fixes idempotency for operations across caching changes (promote,
flush and cache mode changes).

Fixes: #8935
Signed-off-by: Sage Weil <sage@redhat.com>
src/osd/ReplicatedPG.cc
src/osd/ReplicatedPG.h
src/osdc/Objecter.h

index e0e1830aa8cac869f34e212c3db536ae903a8989..5f74fe57f5502a03c5b2f451180eb0ef8ebefaf3 100644 (file)
@@ -1451,6 +1451,11 @@ void ReplicatedPG::do_op(OpRequestRef& op)
 
   // dup/replay?
   if (op->may_write() || op->may_cache()) {
+    // warning: we will get back *a* request for this reqid, but not
+    // necessarily the most recent.  this happens with flush and
+    // promote ops, but we can't possible have both in our log where
+    // the original request is still not stable on disk, so for our
+    // purposes here it doesn't matter which one we get.
     const pg_log_entry_t *entry = pg_log.get_log().get_request(m->get_reqid());
     if (entry) {
       const eversion_t& oldv = entry->version;
@@ -5923,6 +5928,10 @@ void ReplicatedPG::finish_ctx(OpContext *ctx, int log_op_type, bool maintain_ssc
   }
 
   ctx->log.back().mod_desc.claim(ctx->mod_desc);
+  if (!ctx->extra_reqids.empty()) {
+    dout(20) << __func__ << "  extra_reqids " << ctx->extra_reqids << dendl;
+    ctx->log.back().extra_reqids.swap(ctx->extra_reqids);
+  }
 
   // apply new object state.
   ctx->obc->obs = ctx->new_obs;
@@ -6169,12 +6178,20 @@ int ReplicatedPG::fill_in_copy_get(
     }
   }
 
+  if (cursor.is_complete()) {
+    // include reqids only in the final step.  this is a bit fragile
+    // but it works...
+    pg_log.get_log().get_object_reqids(ctx->obc->obs.oi.soid, 10, &reply_obj.reqids);
+    dout(20) << " got reqids" << dendl;
+  }
+
   dout(20) << " cursor.is_complete=" << cursor.is_complete()
           << " " << out_attrs.size() << " attrs"
           << " " << bl.length() << " bytes"
           << " " << reply_obj.omap_header.length() << " omap header bytes"
           << " " << reply_obj.omap_data.length() << " omap data bytes in "
           << omap_keys << " keys"
+          << " " << reply_obj.reqids.size() << " reqids"
           << dendl;
   reply_obj.cursor = cursor;
   if (!async_read_started) {
@@ -6264,6 +6281,7 @@ void ReplicatedPG::_copy_some(ObjectContextRef obc, CopyOpRef cop)
              &cop->results.flags,
              &cop->results.source_data_digest,
              &cop->results.source_omap_digest,
+             &cop->results.reqids,
              &cop->rval);
 
   C_Copyfrom *fin = new C_Copyfrom(this, obc->obs.oi.soid,
@@ -6561,6 +6579,8 @@ void ReplicatedPG::finish_copyfrom(OpContext *ctx)
   obs.oi.set_data_digest(cb->results->data_digest);
   obs.oi.set_omap_digest(cb->results->omap_digest);
 
+  ctx->extra_reqids = cb->results->reqids;
+
   // cache: clear whiteout?
   if (obs.oi.is_whiteout()) {
     dout(10) << __func__ << " clearing whiteout on " << obs.oi.soid << dendl;
@@ -6681,6 +6701,8 @@ void ReplicatedPG::finish_promote(int r, CopyResults *results,
     ++tctx->delta_stats.num_object_clones;
   tctx->new_obs.exists = true;
 
+  tctx->extra_reqids = results->reqids;
+
   if (whiteout) {
     // create a whiteout
     tctx->op_t->touch(soid);
index 5ece595016846c5ca77a5066c68b0934c872b99f..44bf13e50856169008feafefa32eeaf5421acafc 100644 (file)
@@ -126,6 +126,7 @@ public:
     uint32_t flags;    // object_copy_data_t::FLAG_*
     uint32_t source_data_digest, source_omap_digest;
     uint32_t data_digest, omap_digest;
+    vector<osd_reqid_t> reqids;
     bool is_data_digest() {
       return flags & object_copy_data_t::FLAG_DATA_DIGEST;
     }
@@ -531,6 +532,8 @@ public:
     int num_read;    ///< count read ops
     int num_write;   ///< count update ops
 
+    vector<osd_reqid_t> extra_reqids;
+
     CopyFromCallback *copy_cb;
 
     hobject_t new_temp_oid, discard_temp_oid;  ///< temp objects we should start/stop tracking
index fb3aa392f956f479d94482440b7861ab6b97a7dd..ff7cb891f72a625fefd1626e55b994a89d619f7b 100644 (file)
@@ -625,6 +625,7 @@ struct ObjectOperation {
     uint32_t *out_flags;
     uint32_t *out_data_digest;
     uint32_t *out_omap_digest;
+    vector<osd_reqid_t> *out_reqids;
     int *prval;
     C_ObjectOperation_copyget(object_copy_cursor_t *c,
                              uint64_t *s,
@@ -637,13 +638,14 @@ struct ObjectOperation {
                              uint32_t *flags,
                              uint32_t *dd,
                              uint32_t *od,
+                             vector<osd_reqid_t> *oreqids,
                              int *r)
       : cursor(c),
        out_size(s), out_mtime(m),
        out_attrs(a), out_data(d), out_omap_header(oh),
        out_omap_data(o), out_snaps(osnaps), out_snap_seq(osnap_seq),
        out_flags(flags), out_data_digest(dd), out_omap_digest(od),
-       prval(r) {}
+        out_reqids(oreqids), prval(r) {}
     void finish(int r) {
       if (r < 0)
        return;
@@ -673,6 +675,8 @@ struct ObjectOperation {
          *out_data_digest = copy_reply.data_digest;
        if (out_omap_digest)
          *out_omap_digest = copy_reply.omap_digest;
+       if (out_reqids)
+         *out_reqids = copy_reply.reqids;
        *cursor = copy_reply.cursor;
       } catch (buffer::error& e) {
        if (prval)
@@ -694,6 +698,7 @@ struct ObjectOperation {
                uint32_t *out_flags,
                uint32_t *out_data_digest,
                uint32_t *out_omap_digest,
+               vector<osd_reqid_t> *out_reqids,
                int *prval) {
     OSDOp& osd_op = add_op(CEPH_OSD_OP_COPY_GET);
     osd_op.op.copy_get.max = max;
@@ -706,7 +711,7 @@ struct ObjectOperation {
                                     out_attrs, out_data, out_omap_header,
                                    out_omap_data, out_snaps, out_snap_seq,
                                    out_flags, out_data_digest, out_omap_digest,
-                                   prval);
+                                   out_reqids, prval);
     out_bl[p] = &h->bl;
     out_handler[p] = h;
   }