]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
ReplicatedPG: copy: start defining CopyCallback structures
authorGreg Farnum <greg@inktank.com>
Tue, 1 Oct 2013 19:49:04 +0000 (12:49 -0700)
committerGreg Farnum <greg@inktank.com>
Tue, 1 Oct 2013 23:50:56 +0000 (16:50 -0700)
Outline the basic interfaces we're going to use, and implement
the more obvious ones.

Signed-off-by: Greg Farnum <greg@inktank.com>
src/osd/ReplicatedPG.h

index c4384e340579eeed3bc33a0c956b75c39b258d8b..a93f53be4144922320dcaf8bbd8c53e7436288ab 100644 (file)
@@ -93,6 +93,7 @@ public:
    * state associated with a copy operation
    */
   struct OpContext;
+  class CopyCallback;
 
   struct CopyOp {
     OpContext *ctx;
@@ -126,6 +127,62 @@ public:
   };
   typedef boost::shared_ptr<CopyOp> CopyOpRef;
 
+  /**
+   * 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
+   * 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 {
+  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) {}
+    virtual void finish(int r) { result_code = r; }
+  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) {}
+  public:
+    OpContext *ctx;
+    hobject_t temp_obj;
+    CopyFromCallback(OpContext *ctx_, const hobject_t& temp_obj_) :
+      ctx(ctx_), temp_obj(temp_obj_) {}
+    void copy_complete_ops(ObjectStore::Transaction& t);
+    ~CopyFromCallback() {}
+  };
+
   boost::scoped_ptr<PGBackend> pgbackend;
 
   /// Listener methods