From efee7466c57fb118ab14696c614f491ab3faa5fa Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 31 May 2011 14:28:52 -0700 Subject: [PATCH] objecter, osd: clonerange operation 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 --- src/include/ceph_strings.cc | 1 + src/include/rados.h | 7 +++++++ src/messages/MOSDOp.h | 11 ++++++++++- src/osd/osd_types.h | 5 +++++ src/osdc/Objecter.cc | 1 + src/osdc/Objecter.h | 18 ++++++++++++++++++ 6 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/include/ceph_strings.cc b/src/include/ceph_strings.cc index ecc7ac03e8a47..0768b3e5d083a 100644 --- a/src/include/ceph_strings.cc +++ b/src/include/ceph_strings.cc @@ -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"; diff --git a/src/include/rados.h b/src/include/rados.h index ea6ab63b56d9e..a6f918036201e 100644 --- a/src/include/rados.h +++ b/src/include/rados.h @@ -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)); diff --git a/src/messages/MOSDOp.h b/src/messages/MOSDOp.h index 3daf005f9b455..838d07d1b57a5 100644 --- a/src/messages/MOSDOp.h +++ b/src/messages/MOSDOp.h @@ -42,6 +42,7 @@ private: pg_t pgid; public: vector ops; + vector 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; diff --git a/src/osd/osd_types.h b/src/osd/osd_types.h index c3eccc76dfa99..e356f50c615a1 100644 --- a/src/osd/osd_types.h +++ b/src/osd/osd_types.h @@ -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) diff --git a/src/osdc/Objecter.cc b/src/osdc/Objecter.cc index b8bfccf9d8765..1270a3338fe2e 100644 --- a/src/osdc/Objecter.cc +++ b/src/osdc/Objecter.cc @@ -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++); diff --git a/src/osdc/Objecter.h b/src/osdc/Objecter.h index 3044c01c93ca3..73129bbfc4941 100644 --- a/src/osdc/Objecter.h +++ b/src/osdc/Objecter.h @@ -48,6 +48,7 @@ struct ObjectOperation { vector ops; int flags; int priority; + vector 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 src_oids; pg_t pgid; vector 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, -- 2.39.5