]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
ReplicatedPG: copy: switch CopyCallback to use a GenContext
authorGreg Farnum <greg@inktank.com>
Fri, 4 Oct 2013 16:10:20 +0000 (09:10 -0700)
committerGreg Farnum <greg@inktank.com>
Fri, 4 Oct 2013 19:58:58 +0000 (12:58 -0700)
Signed-off-by: Greg Farnum <greg@inktank.com>
src/osd/ReplicatedPG.cc
src/osd/ReplicatedPG.h

index 6118a25d510c882b1c64c39382f6f68e72a61f1d..ce5d347cb3bc2d50fed0fa63c1a0edcaece1f2e7 100644 (file)
@@ -4456,6 +4456,7 @@ void ReplicatedPG::process_copy_chunk(hobject_t oid, tid_t tid, int r)
   ObjectContextRef obc = cop->obc;
   cop->objecter_tid = 0;
 
+  CopyResults results;
   if (r >= 0) {
     assert(cop->rval >= 0);
 
@@ -4483,15 +4484,14 @@ void ReplicatedPG::process_copy_chunk(hobject_t oid, tid_t tid, int r)
       _copy_some(obc, cop);
       return;
     } else {
-      ObjectStore::Transaction t;
-      _build_finish_copy_transaction(cop, t);
-      cop->cb->copy_complete_ops(t);
-      cop->cb->set_data_size(cop->temp_cursor.data_offset);
+      _build_finish_copy_transaction(cop, results.get<3>());
+      results.get<1>() = cop->temp_cursor.data_offset;
     }
   }
 
   dout(20) << __func__ << " complete; committing" << dendl;
-  cop->cb->complete(cop->rval);
+  results.get<0>() = cop->rval;
+  cop->cb->complete(results);
 
   copy_ops.erase(obc->obs.oi.soid);
   --obc->copyfrom_readside;
@@ -4556,8 +4556,8 @@ int ReplicatedPG::finish_copyfrom(OpContext *ctx)
   if (cb->is_temp_obj_used()) {
     ctx->discard_temp_oid = cb->temp_obj;
   }
-  ctx->op_t.swap(cb->final_tx);
-  ctx->op_t.append(cb->final_tx);
+  ctx->op_t.swap(cb->results.get<3>());
+  ctx->op_t.append(cb->results.get<3>());
 
   interval_set<uint64_t> ch;
   if (obs.oi.size > 0)
@@ -4591,7 +4591,9 @@ void ReplicatedPG::cancel_copy(CopyOpRef cop)
   --cop->obc->copyfrom_readside;
 
   kick_object_context_blocked(cop->obc);
-  cop->cb->complete(-ECANCELED);
+  bool temp_obj_created = !cop->cursor.is_initial();
+  CopyResults result(-ECANCELED, 0, temp_obj_created, ObjectStore::Transaction());
+  cop->cb->complete(result);
 }
 
 void ReplicatedPG::cancel_copy_ops()
index f7e677f7b8470d815ab38dbaf843aea835383e62..2a8b722c752c82fd983a8883967eab8a0ac0fa90 100644 (file)
@@ -18,6 +18,7 @@
 #define CEPH_REPLICATEDPG_H
 
 #include <boost/optional.hpp>
+#include <boost/tuple/tuple.hpp>
 
 #include "include/assert.h" 
 #include "common/cmdparse.h"
@@ -131,54 +132,49 @@ public:
    * The CopyCallback class defines an interface for completions to the
    * copy_start code. Users of the copy infrastructure must implement
    * one and give an instance of the class to start_copy.
-   * In particular,
-   * 1) Once the copy code has placed data in the temp object, it calls
-   * the data_in_temp_obj() function.
-   * 2) if everything has succeeded, it may call copy_complete_ops() and
-   * pass in a Transaction which contains the ops that must be executed
-   * in order to complete the copy. The implementer must make sure these ops
-   * are executed if they are provide (at present, they are).
-   * 3) If everything has succeeded, it will call data_size() with the
-   * size of copied object
-   * 4) It will call finish().
    *
    * The implementer is responsible for making sure that the CopyCallback
    * can associate itself with the correct copy operation. The presence
-   * of copy_complete_ops ensures that write operations can be performed
+   * of the closing Transaction ensures that write operations can be performed
    * atomically with the copy being completed (which doing them in separate
    * transactions would not allow); if you are doing the copy for a read
    * op you will have to generate a separate op to finish the copy with.
    */
-  class CopyCallback : public Context {
+  /// return code, total object size, data in temp object?, final Transaction
+  typedef boost::tuple<int, size_t, bool, ObjectStore::Transaction> CopyResults;
+  class CopyCallback : public GenContext<CopyResults&> {
   protected:
-    bool data_in_temp;
-    uint64_t data_size;
-    int result_code;
-
-    CopyCallback() : data_in_temp(false), data_size((uint64_t)-1),
-       result_code(0) {}
+    CopyCallback() {}
     /**
-     * @param r The copy return code. 0 for success; -ECANCELLED if
+     * results.get<0>() is the return code: 0 for success; -ECANCELLED if
      * the operation was cancelled by the local OSD; -errno for other issues.
+     * results.get<1>() is the total size of the object (for updating pg stats)
+     * results.get<2>() indicates whether we have already written data to
+     * the temp object (so it needs to get cleaned up, if the return code
+     * indicates a failure)
+     * results.get<3>() is a Transaction; if non-empty you need to perform
+     * its results before any other accesses to the object in order to
+     * complete the copy.
      */
-    virtual void finish(int r) { result_code = r; }
+    virtual void finish(CopyResults& results_) = 0;
+
   public:
-    /// Give the CopyCallback ops to perform to complete the copy
-    virtual void copy_complete_ops(ObjectStore::Transaction& t) = 0;
-    /// Tell the CopyCallback that there is now data in the temp object
-    virtual void data_in_temp_obj() { data_in_temp = true; };
-    bool is_temp_obj_used() { return data_in_temp; }
     /// Provide the final size of the copied object to the CopyCallback
-    virtual void set_data_size(uint64_t size) { data_size = size; }
-    uint64_t get_data_size() { return data_size; }
-    int get_result() { return result_code; }
     virtual ~CopyCallback() {};
   };
 
   class CopyFromCallback: public CopyCallback {
-  protected:
-    virtual void finish(int r) {
-      result_code = r;
+  public:
+    CopyResults results;
+    OpContext *ctx;
+    hobject_t temp_obj;
+    CopyFromCallback(OpContext *ctx_, const hobject_t& temp_obj_) :
+      ctx(ctx_), temp_obj(temp_obj_) {}
+    ~CopyFromCallback() {}
+
+    virtual void finish(CopyResults& results_) {
+      results = results_;
+      int r = results.get<0>();
       if (r >= 0) {
        ctx->pg->execute_ctx(ctx);
       }
@@ -191,14 +187,10 @@ public:
        }
       }
     }
-  public:
-    OpContext *ctx;
-    hobject_t temp_obj;
-    ObjectStore::Transaction final_tx;
-    CopyFromCallback(OpContext *ctx_, const hobject_t& temp_obj_) :
-      ctx(ctx_), temp_obj(temp_obj_) {}
-    void copy_complete_ops(ObjectStore::Transaction& t) { final_tx.swap(t); }
-    ~CopyFromCallback() {}
+
+    bool is_temp_obj_used() { return results.get<2>(); }
+    uint64_t get_data_size() { return results.get<1>(); }
+    int get_result() { return results.get<0>(); }
   };
   friend class CopyFromCallback;
 
@@ -375,7 +367,7 @@ public:
     int num_read;    ///< count read ops
     int num_write;   ///< count update ops
 
-    CopyCallback *copy_cb;
+    CopyFromCallback *copy_cb;
 
     hobject_t new_temp_oid, discard_temp_oid;  ///< temp objects we should start/stop tracking