case CEPH_OSD_OP_COPY_GET_CLASSIC:
++ctx->num_read;
- result = fill_in_copy_get(bp, osd_op, oi, true);
+ result = fill_in_copy_get(bp, osd_op, ctx->obc, true);
if (result == -EINVAL)
goto fail;
break;
case CEPH_OSD_OP_COPY_GET:
++ctx->num_read;
- result = fill_in_copy_get(bp, osd_op, oi, false);
+ result = fill_in_copy_get(bp, osd_op, ctx->obc, false);
if (result == -EINVAL)
goto fail;
break;
};
int ReplicatedPG::fill_in_copy_get(bufferlist::iterator& bp, OSDOp& osd_op,
- object_info_t& oi, bool classic)
+ ObjectContextRef& obc, bool classic)
{
+ object_info_t& oi = obc->obs.oi;
hobject_t& soid = oi.soid;
int result = 0;
object_copy_cursor_t cursor;
reply_obj.size = oi.size;
reply_obj.mtime = oi.mtime;
reply_obj.category = oi.category;
- reply_obj.snaps = oi.snaps;
+ if (soid.snap < CEPH_NOSNAP) {
+ reply_obj.snaps = oi.snaps;
+ } else {
+ assert(obc->ssc);
+ reply_obj.snap_seq = obc->ssc->snapset.seq;
+ }
// attrs
map<string,bufferlist>& out_attrs = reply_obj.attrs;
&cop->results->object_size, &cop->results->mtime,
&cop->results->category,
&cop->attrs, &cop->data, &cop->omap_header, &cop->omap,
- &cop->results->snaps,
+ &cop->results->snaps, &cop->results->snap_seq,
&cop->rval);
C_Copyfrom *fin = new C_Copyfrom(this, obc->obs.oi.soid,
version_t user_version; ///< The copy source's user version
bool should_requeue; ///< op should be requeued on cancel
vector<snapid_t> snaps; ///< src's snaps (if clone)
+ snapid_t snap_seq; ///< src's snap_seq (if head)
librados::snap_set_t snapset; ///< src snapset (if head)
bool mirror_snapset;
CopyResults() : object_size(0), started_temp_obj(false),
map<hobject_t, CopyOpRef> copy_ops;
int fill_in_copy_get(bufferlist::iterator& bp, OSDOp& op,
- object_info_t& oi, bool classic);
+ ObjectContextRef& obc, bool classic);
/**
* To copy an object, call start_copy.
*
::encode(cursor, bl);
::encode(omap_header, bl);
::encode(snaps, bl);
+ ::encode(snap_seq, bl);
ENCODE_FINISH(bl);
}
::decode(cursor, bl);
if (struct_v >= 2)
::decode(omap_header, bl);
- if (struct_v >= 3)
+ if (struct_v >= 3) {
::decode(snaps, bl);
+ ::decode(snap_seq, bl);
+ } else {
+ snaps.clear();
+ snap_seq = 0;
+ }
DECODE_FINISH(bl);
}
/// which snaps we are defined for (if a snap and not the head)
vector<snapid_t> snaps;
+ ///< latest snap seq for the object (if head)
+ snapid_t snap_seq;
public:
object_copy_data_t() : size((uint64_t)-1) {}
bufferlist *out_data, *out_omap_header;
std::map<std::string,bufferlist> *out_omap;
vector<snapid_t> *out_snaps;
+ snapid_t *out_snap_seq;
int *prval;
C_ObjectOperation_copyget(object_copy_cursor_t *c,
uint64_t *s,
bufferlist *d, bufferlist *oh,
std::map<std::string,bufferlist> *o,
std::vector<snapid_t> *osnaps,
+ snapid_t *osnap_seq,
int *r)
: cursor(c),
out_size(s), out_mtime(m), out_category(cat),
out_attrs(a), out_data(d), out_omap_header(oh),
- out_omap(o), out_snaps(osnaps), prval(r) {}
+ out_omap(o), out_snaps(osnaps), out_snap_seq(osnap_seq),
+ prval(r) {}
void finish(int r) {
if (r < 0)
return;
*out_omap = copy_reply.omap;
if (out_snaps)
*out_snaps = copy_reply.snaps;
+ if (out_snap_seq)
+ *out_snap_seq = copy_reply.snap_seq;
*cursor = copy_reply.cursor;
} catch (buffer::error& e) {
if (prval)
bufferlist *out_omap_header,
std::map<std::string,bufferlist> *out_omap,
vector<snapid_t> *out_snaps,
+ snapid_t *out_snap_seq,
int *prval) {
OSDOp& osd_op = add_op(CEPH_OSD_OP_COPY_GET);
osd_op.op.copy_get.max = max;
C_ObjectOperation_copyget *h =
new C_ObjectOperation_copyget(cursor, out_size, out_mtime, out_category,
out_attrs, out_data, out_omap_header,
- out_omap, out_snaps, prval);
+ out_omap, out_snaps, out_snap_seq, prval);
out_bl[p] = &h->bl;
out_handler[p] = h;
}