]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
Merge pull request #676 from ceph/wip-start-copy
authorGregory Farnum <greg@inktank.com>
Fri, 4 Oct 2013 22:58:50 +0000 (15:58 -0700)
committerGregory Farnum <greg@inktank.com>
Fri, 4 Oct 2013 22:58:50 +0000 (15:58 -0700)
Reviewed-by: Samuel Just <sam.just@inktank.com>
1  2 
src/osd/ReplicatedPG.cc
src/osd/ReplicatedPG.h

Simple merge
index 5abfc4cea56e7fb8fceb1669b30448b6dd14a0af,f337a8f4202233e67984195e4d3d885992071b46..c277c0d3f86884e8d02f78693d46f94b71605fca
@@@ -123,10 -128,72 +128,75 @@@ 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.
+    *
+    * The implementer is responsible for making sure that the CopyCallback
+    * can associate itself with the correct copy operation. The presence
+    * 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.
+    */
+   /// 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:
+     CopyCallback() {}
+     /**
+      * 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(CopyResults& results_) = 0;
+   public:
+     /// Provide the final size of the copied object to the CopyCallback
+     virtual ~CopyCallback() {};
+   };
+   class CopyFromCallback: public CopyCallback {
+   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);
+       }
+       ctx->copy_cb = NULL;
+       if (r < 0) {
+       if (r != -ECANCELED) { // on cancel just toss it out; client resends
+         ctx->pg->osd->reply_op_error(ctx->op, r);
+       }
+       delete ctx;
+       }
+     }
+     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;
    boost::scoped_ptr<PGBackend> pgbackend;
 +  PGBackend *get_pgbackend() {
 +    return pgbackend.get();
 +  }
  
    /// Listener methods
    void on_local_recover_start(