waiting_for_missing_object[soid].push_back(m);
}
+void ReplicatedPG::wait_for_all_missing(Message *m)
+{
+ waiting_for_all_missing.push_back(m);
+}
+
bool ReplicatedPG::is_degraded_object(const hobject_t& soid)
{
if (missing.missing.count(soid))
// ==========================================================
+bool ReplicatedPG::pg_op_must_wait(MOSDOp *op)
+{
+ if (missing.missing.empty())
+ return false;
+ for (vector<OSDOp>::iterator p = op->ops.begin(); p != op->ops.end(); ++p) {
+ if (p->op.op == CEPH_OSD_OP_PGLS) {
+ if (op->get_snapid() != CEPH_NOSNAP) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
void ReplicatedPG::do_pg_op(MOSDOp *op)
{
dout(10) << "do_pg_op " << *op << dendl;
*/
void ReplicatedPG::do_op(MOSDOp *op)
{
- if ((op->get_rmw_flags() & CEPH_OSD_FLAG_PGOP))
+ if ((op->get_rmw_flags() & CEPH_OSD_FLAG_PGOP)) {
+ if (pg_op_must_wait(op)) {
+ wait_for_all_missing(op);
+ return;
+ }
return do_pg_op(op);
+ }
dout(10) << "do_op " << *op << (op->may_write() ? " may_write" : "") << dendl;
dout(20) << " kicking waiters on " << soid << dendl;
osd->requeue_ops(this, waiting_for_missing_object[soid]);
waiting_for_missing_object.erase(soid);
+ if (missing.missing.size() == 0) {
+ osd->requeue_ops(this, waiting_for_all_missing);
+ waiting_for_all_missing.clear();
+ }
} else {
dout(20) << " no waiters on " << soid << dendl;
/*for (hash_map<hobject_t,list<class Message*> >::iterator p = waiting_for_missing_object.begin();
void ReplicatedPG::_finish_mark_all_unfound_lost(list<ObjectContext*>& obcs)
{
- dout(10) << "_finish_mark_all_unfound_lost " << dendl;
lock();
+ dout(10) << "_finish_mark_all_unfound_lost " << dendl;
+
+ osd->requeue_ops(this, waiting_for_all_missing);
+ waiting_for_all_missing.clear();
+
while (!obcs.empty()) {
ObjectContext *obc = obcs.front();
put_object_context(obc);
// take object waiters
requeue_object_waiters(waiting_for_missing_object);
requeue_object_waiters(waiting_for_degraded_object);
+ osd->requeue_ops(this, waiting_for_all_missing);
+ waiting_for_all_missing.clear();
// clear pushing/pulling maps
pushing.clear();
void do_op(MOSDOp *op);
+ bool pg_op_must_wait(MOSDOp *op);
void do_pg_op(MOSDOp *op);
void do_sub_op(MOSDSubOp *op);
void do_sub_op_reply(MOSDSubOpReply *op);
bool is_missing_object(const hobject_t& oid);
void wait_for_missing_object(const hobject_t& oid, Message *op);
+ void wait_for_all_missing(Message *op);
bool is_degraded_object(const hobject_t& oid);
void wait_for_degraded_object(const hobject_t& oid, Message *op);