}
-int ReplicatedPG::do_read_ops(MOSDOp *op, OpContext& ctx,
- bufferlist::iterator& bp,
- bufferlist& data,
- int *data_off)
+int ReplicatedPG::do_read_ops(ReadOpContext *ctx,
+ bufferlist::iterator& bp, bufferlist& data)
{
int result = 0;
- sobject_t& soid = ctx.soid;
- object_info_t& oi = ctx.oi;
- vector<ceph_osd_op> &ops = ctx.ops;
+
+ vector<ceph_osd_op>& ops = ctx->ops;
+ object_info_t& oi = ctx->oi;
+ const sobject_t& soid = oi.soid;
for (vector<ceph_osd_op>::iterator p = ops.begin(); p != ops.end(); p++) {
switch (p->op) {
// read into a buffer
bufferlist bl;
int r = osd->store->read(info.pgid.to_coll(), soid, p->offset, p->length, bl);
- if (data.length() == 0 && data_off)
- *data_off = p->offset;
+ if (data.length() == 0)
+ ctx->data_off = p->offset;
data.claim(bl);
if (r >= 0)
p->length = r;
//dout(20) << "rdcall param=" << indata.c_str() << dendl;
ClassHandler::ClassData *cls;
- result = osd->get_class(cname, info.pgid, op, &cls);
+ result = osd->get_class(cname, info.pgid, ctx->op, &cls);
if (result) {
dout(10) << "rdcall class " << cname << " does not exist" << dendl;
if (result == -EAGAIN)
break;
case CEPH_OSD_OP_MASKTRUNC:
- if (p != op->ops.begin()) {
+ if (p != ops.begin()) {
ceph_osd_op& rd = *(p - 1);
ceph_osd_op& m = *p;
void ReplicatedPG::op_read(MOSDOp *op)
{
object_t oid = op->get_oid();
- sobject_t soid(oid, op->get_snapid());
+ ReadOpContext ctx(op, op->ops, sobject_t(op->get_oid(), op->get_snapid()));
+ sobject_t& soid = ctx.oi.soid;
- dout(10) << "op_read " << soid << " " << op->ops << dendl;
+ dout(10) << "op_read " << soid << " " << ctx.ops << dendl;
bufferlist::iterator bp = op->get_data().begin();
bufferlist data;
- int data_off = 0;
int result = 0;
// pick revision
- object_info_t oi(soid);
if (soid.snap) {
- result = pick_read_snap(soid, oi);
+ result = pick_read_snap(soid, ctx.oi);
if (result == -EAGAIN) {
wait_for_missing_object(soid, op);
return;
// wrlocked?
if ((op->get_snapid() == 0 || op->get_snapid() == CEPH_NOSNAP) &&
- block_if_wrlocked(op, oi))
+ block_if_wrlocked(op, ctx.oi))
return;
}
}
- {
- OpContext ctx(soid, oi, op->ops);
-
- // do it.
- result = do_read_ops(op, ctx, bp, data, &data_off);
- if (result == -EAGAIN)
- return;
- }
+ // do it.
+ result = do_read_ops(&ctx, bp, data);
+ if (result == -EAGAIN)
+ return;
done:
// reply
MOSDOpReply *reply = new MOSDOpReply(op, 0, osd->osdmap->get_epoch(), CEPH_OSD_FLAG_ACK);
reply->set_data(data);
- reply->get_header().data_off = data_off;
+ reply->get_header().data_off = ctx.data_off;
reply->set_result(result);
if (result >= 0) {
stat_object_temp_rd[soid].hit(now); // hit temp.
}
-
osd->messenger->send_message(reply, op->get_orig_source_inst());
delete op;
}
assert(r >= 0);
pinfo->oi.decode(bv);
} else {
- pinfo->oi.poid = poid;
+ pinfo->oi.soid = poid;
pinfo->exists = false;
pinfo->size = 0;
}
class ReplicatedPG : public PG {
public:
+ /*
+ * Capture all object state associated with an in-progress read.
+ */
+ struct ReadOpContext {
+ MOSDOp *op;
+ vector<ceph_osd_op>& ops;
+
+ object_info_t oi;
+ int data_off; // FIXME: we may want to kill this msgr hint off at some point!
+
+ ReadOpContext(MOSDOp *_op, vector<ceph_osd_op>& _ops, sobject_t _soid) :
+ op(_op), ops(_ops), oi(_soid), data_off(0) {}
+ };
+
+
/*
* keep tabs on object modifications that are in flight.
* we need to know the projected existence, size, snapset,
ProjectedObjectInfo() : ref(0), exists(false), size(0), oi(poid) {}
};
-
/*
* gather state on the primary/head while replicating an osd op.
*/
}
};
- struct OpContext {
- sobject_t& soid;
- object_info_t& oi;
- vector<ceph_osd_op>& ops;
- OpContext(sobject_t& _soid, object_info_t& _oi,
- vector<ceph_osd_op>& _ops) : soid(_soid), oi(_oi), ops(_ops) {}
- };
protected:
void op_read(MOSDOp *op);
void op_modify(MOSDOp *op);
- int do_read_ops(MOSDOp *op, OpContext& ctx,
- bufferlist::iterator& bp,
- bufferlist& data,
- int *data_off);
+ int do_read_ops(ReadOpContext *ctx, bufferlist::iterator& bp, bufferlist& data);
void sub_op_modify(MOSDSubOp *op);
void sub_op_modify_reply(MOSDSubOpReply *reply);
#define OI_ATTR "_"
struct object_info_t {
- pobject_t poid;
+ sobject_t soid;
eversion_t version, prior_version;
osd_reqid_t last_reqid;
bufferlist truncate_info; // bah.. messy layering.
void encode(bufferlist& bl) const {
- ::encode(poid, bl);
+ ::encode(soid, bl);
::encode(version, bl);
::encode(prior_version, bl);
::encode(last_reqid, bl);
::encode(mtime, bl);
- if (poid.snap == CEPH_NOSNAP) {
+ if (soid.snap == CEPH_NOSNAP) {
::encode(snapset, bl);
::encode(wrlock_by, bl);
} else
::encode(truncate_info, bl);
}
void decode(bufferlist::iterator& bl) {
- ::decode(poid, bl);
+ ::decode(soid, bl);
::decode(version, bl);
::decode(prior_version, bl);
::decode(last_reqid, bl);
::decode(mtime, bl);
- if (poid.snap == CEPH_NOSNAP) {
+ if (soid.snap == CEPH_NOSNAP) {
::decode(snapset, bl);
::decode(wrlock_by, bl);
} else
decode(p);
}
- object_info_t(pobject_t p) : poid(p) {}
+ object_info_t(sobject_t s) : soid(s) {}
object_info_t(bufferlist& bl) {
decode(bl);
}
inline ostream& operator<<(ostream& out, const object_info_t& oi) {
- out << oi.poid << "(" << oi.version
+ out << oi.soid << "(" << oi.version
<< " " << oi.last_reqid;
if (oi.wrlock_by.tid)
out << " wrlock_by=" << oi.wrlock_by;
- if (oi.poid.snap == CEPH_NOSNAP)
+ if (oi.soid.snap == CEPH_NOSNAP)
out << " " << oi.snapset << ")";
else
out << " " << oi.snaps << ")";