summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Farnum <greg@inktank.com>2013-10-01 12:49:04 -0700
committerGreg Farnum <greg@inktank.com>2013-10-01 16:50:56 -0700
commit0b472766f11e3bf30012d2958bf0564aa9354e17 (patch)
tree0baaecf21c60aca844a9885e8bad24782e1603d0
parent1784ef96f474ccc9a7f2d8ea8d6ce90daddd1fdb (diff)
downloadceph-0b472766f11e3bf30012d2958bf0564aa9354e17.tar.gz
ReplicatedPG: copy: start defining CopyCallback structures
Outline the basic interfaces we're going to use, and implement the more obvious ones. Signed-off-by: Greg Farnum <greg@inktank.com>
-rw-r--r--src/osd/ReplicatedPG.h57
1 files changed, 57 insertions, 0 deletions
diff --git a/src/osd/ReplicatedPG.h b/src/osd/ReplicatedPG.h
index c4384e34057..a93f53be414 100644
--- a/src/osd/ReplicatedPG.h
+++ b/src/osd/ReplicatedPG.h
@@ -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