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";
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,
__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));
pg_t pgid;
public:
vector<OSDOp> ops;
+ vector<object_t> src_oids;
private:
snapid_t snapid;
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);
if (flags & CEPH_OSD_FLAG_PEERSTAT)
::encode(peer_stat, payload);
+
+ ::encode(src_oids, payload);
}
}
if (flags & CEPH_OSD_FLAG_PEERSTAT)
::decode(peer_stat, p);
+
+ if (header.version >= 3)
+ ::decode(src_oids, p);
}
unsigned off = 0;
if (snapid != CEPH_NOSNAP)
out << "@" << snapid;
+ if (src_oids.size())
+ out << " src " << src_oids;
+
if (oloc.key.size())
out << " " << oloc;
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)
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++);
vector<OSDOp> ops;
int flags;
int priority;
+ vector<object_t> src_oids;
ObjectOperation() : flags(0), priority(0) {}
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);
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;
object_t oid;
object_locator_t oloc;
+ vector<object_t> src_oids;
pg_t pgid;
vector<int> acting;
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,