]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
objecter, osd: clonerange operation
authorSage Weil <sage@newdream.net>
Tue, 31 May 2011 21:28:52 +0000 (14:28 -0700)
committerSage Weil <sage@newdream.net>
Tue, 31 May 2011 21:28:52 +0000 (14:28 -0700)
Add a src_oids field to MOSDOp, referenced by a new CLONERANGE osd op type
that will clone data from one object to another.

- The src_oids will need to have the same locator as the destination object
  type to ensure this operation can succeed.
- The OSD is going to have to do extra work to ensure the src object(s)
  are readable, etc., at the time of the clone.

Signed-off-by: Sage Weil <sage@newdream.net>
src/include/ceph_strings.cc
src/include/rados.h
src/messages/MOSDOp.h
src/osd/osd_types.h
src/osdc/Objecter.cc
src/osdc/Objecter.h

index ecc7ac03e8a47311c99354ad90b7c944af205516..0768b3e5d083a15e8d31021b781aa4588c0941aa 100644 (file)
@@ -44,6 +44,7 @@ const char *ceph_osd_op_name(int op)
        case CEPH_OSD_OP_TMAPGET: return "tmapget";
        case CEPH_OSD_OP_TMAPPUT: return "tmapput";
        case CEPH_OSD_OP_WATCH: return "watch";
+       case CEPH_OSD_OP_CLONERANGE: return "clonerange";
 
        case CEPH_OSD_OP_GETXATTR: return "getxattr";
        case CEPH_OSD_OP_GETXATTRS: return "getxattrs";
index ea6ab63b56d9e5cab3e13295e253266af92f70a9..a6f918036201e186b07344ddb137765ec47d78be 100644 (file)
@@ -221,6 +221,8 @@ enum {
 
        CEPH_OSD_OP_WATCH   = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 15,
 
+       CEPH_OSD_OP_CLONERANGE = CEPH_OSD_OP_MODE_WR | CEPH_OSD_OP_TYPE_DATA | 16,
+
        /** attrs **/
        /* read */
        CEPH_OSD_OP_GETXATTR  = CEPH_OSD_OP_MODE_RD | CEPH_OSD_OP_TYPE_ATTR | 1,
@@ -389,6 +391,11 @@ struct ceph_osd_op {
                        __le64 ver;
                        __u8 flag;      /* 0 = unwatch, 1 = watch */
                } __attribute__ ((packed)) watch;
+               struct {
+                       __le64 offset, length;
+                       __le64 src_offset;
+                       __u8 src_oid_idx;
+               } __attribute__ ((packed)) clonerange;
 };
        __le32 payload_len;
 } __attribute__ ((packed));
index 3daf005f9b45562079e3c079b0a76d1cb75a79f8..838d07d1b57a5558afc3e607afa1481c96309e1a 100644 (file)
@@ -42,6 +42,7 @@ private:
   pg_t pgid;
 public:
   vector<OSDOp> ops;
+  vector<object_t> src_oids;
 private:
 
   snapid_t snapid;
@@ -230,7 +231,7 @@ struct ceph_osd_request_head {
       if (flags & CEPH_OSD_FLAG_PEERSTAT)
        ::encode(peer_stat, payload);
     } else {
-      header.version = 2;
+      header.version = 3;
       ::encode(client_inc, payload);
       ::encode(osdmap_epoch, payload);
       ::encode(flags, payload);
@@ -252,6 +253,8 @@ struct ceph_osd_request_head {
 
       if (flags & CEPH_OSD_FLAG_PEERSTAT)
        ::encode(peer_stat, payload);
+
+      ::encode(src_oids, payload);
     }
   }
 
@@ -316,6 +319,9 @@ struct ceph_osd_request_head {
 
       if (flags & CEPH_OSD_FLAG_PEERSTAT)
        ::decode(peer_stat, p);
+
+      if (header.version >= 3)
+       ::decode(src_oids, p);
     }
 
     unsigned off = 0;
@@ -341,6 +347,9 @@ struct ceph_osd_request_head {
     if (snapid != CEPH_NOSNAP)
       out << "@" << snapid;
 
+    if (src_oids.size())
+      out << " src " << src_oids;
+    
     if (oloc.key.size())
       out << " " << oloc;
 
index c3eccc76dfa9990be6c7b11ff26a66ba0a75048d..e356f50c615a18a6657651355f6bea30e073a5b6 100644 (file)
@@ -1533,6 +1533,11 @@ inline ostream& operator<<(ostream& out, const OSDOp& op) {
     case CEPH_OSD_OP_ROLLBACK:
       out << " " << snapid_t(op.op.snap.snapid);
       break;
+    case CEPH_OSD_OP_CLONERANGE:
+      out << " " << op.op.clonerange.offset << "~" << op.op.clonerange.length
+         << " from obj " << op.op.clonerange.src_oid_idx
+         << " offset " << op.op.clonerange.src_offset;
+      break;
     default:
       out << " " << op.op.extent.offset << "~" << op.op.extent.length;
       if (op.op.extent.truncate_seq)
index b8bfccf9d8765a5d234fbd61ce4f10916704feb7..1270a3338fe2e95cc3ad389a873a8c67c1ee1968 100644 (file)
@@ -662,6 +662,7 @@ void Objecter::send_op(Op *op)
   m->get_snaps() = op->snapc.snaps;
 
   m->ops = op->ops;
+  m->src_oids = op->src_oids;
   m->set_mtime(op->mtime);
   m->set_retry_attempt(op->attempts++);
 
index 3044c01c93ca309721ba5003369ae705b990cefb..73129bbfc4941edb0a1dc71ee1dce2b5ecc15b27 100644 (file)
@@ -48,6 +48,7 @@ struct ObjectOperation {
   vector<OSDOp> ops;
   int flags;
   int priority;
+  vector<object_t> src_oids;
 
   ObjectOperation() : flags(0), priority(0) {}
 
@@ -65,6 +66,15 @@ struct ObjectOperation {
     ops[s].op.extent.length = len;
     ops[s].data.claim_append(bl);
   }
+  void add_clone_range(int op, uint64_t off, uint64_t len, uint64_t srcoff, int idx) {
+    int s = ops.size();
+    ops.resize(s+1);
+    ops[s].op.op = op;
+    ops[s].op.clonerange.offset = off;
+    ops[s].op.clonerange.length = len;
+    ops[s].op.clonerange.src_offset = srcoff;
+    ops[s].op.clonerange.src_oid_idx = idx;
+  }
   void add_xattr(int op, const char *name, const bufferlist& data) {
     int s = ops.size();
     ops.resize(s+1);
@@ -168,6 +178,12 @@ struct ObjectOperation {
     add_data(CEPH_OSD_OP_SPARSE_READ, off, len, bl);
   }
 
+  void clone_range(object_t& src_oid, uint64_t src_offset, uint64_t len, uint64_t dst_offset) {
+    bufferlist bl;
+    src_oids.push_back(src_oid);
+    add_clone_range(CEPH_OSD_OP_CLONERANGE, dst_offset, len, src_offset, src_oids.size()-1);
+  }
+
   // object attrs
   void getxattr(const char *name) {
     bufferlist bl;
@@ -287,6 +303,7 @@ public:
     
     object_t oid;
     object_locator_t oloc;
+    vector<object_t> src_oids;
 
     pg_t pgid;
     vector<int> acting;
@@ -629,6 +646,7 @@ private:
     o->priority = op.priority;
     o->mtime = mtime;
     o->snapc = snapc;
+    o->src_oids = op.src_oids;
     return op_submit(o);
   }
   tid_t read(const object_t& oid, const object_locator_t& oloc,