void OSD::handle_op(MOSDOp *op)
{
- if (!op->get_connection()->is_connected()) {
- dout(10) << "handle_op sender " << op->get_connection()->get_peer_addr()
- << " not connected, dropping " << *op << dendl;
+ if (op_is_discardable(op)) {
op->put();
return;
}
pg->put();
}
+bool OSD::op_is_discardable(MOSDOp *op)
+{
+ // drop client request if they are not connected and can't get the
+ // reply anyway. unless this is a replayed op, in which case we
+ // want to do what we can to apply it.
+ if (!op->get_connection()->is_connected() &&
+ op->get_version().version == 0) {
+ dout(10) << " sender " << op->get_connection()->get_peer_addr()
+ << " not connected, dropping " << *op << dendl;
+ return true;
+ }
+ return false;
+}
+
/*
* discard operation, or return true. no side-effects.
*/
return false;
}
+ if (op_is_discardable(op)) {
+ op->put();
+ return false;
+ }
+
// misdirected?
if (op->may_write()) {
if (!pg->is_primary() ||
}
osd_lock.Unlock();
- if (!op->get_connection()->is_connected()) {
- dout(10) << "dequeue_op sender " << op->get_connection()->get_peer_addr()
- << " not connected, dropping " << *op << dendl;
- op->put();
- } else {
- // do it
- if (op->get_type() == CEPH_MSG_OSD_OP)
+ if (op->get_type() == CEPH_MSG_OSD_OP) {
+ if (op_is_discardable((MOSDOp*)op))
+ op->put();
+ else
pg->do_op((MOSDOp*)op); // do it now
- else if (op->get_type() == MSG_OSD_SUBOP)
- pg->do_sub_op((MOSDSubOp*)op);
- else if (op->get_type() == MSG_OSD_SUBOPREPLY)
- pg->do_sub_op_reply((MOSDSubOpReply*)op);
- else
- assert(0);
+ } else if (op->get_type() == MSG_OSD_SUBOP) {
+ pg->do_sub_op((MOSDSubOp*)op);
+ } else if (op->get_type() == MSG_OSD_SUBOPREPLY) {
+ pg->do_sub_op_reply((MOSDSubOpReply*)op);
+ } else {
+ assert(0 == "bad message type in dequeue_op");
}
// unlock and put pg
void handle_sub_op_reply(class MOSDSubOpReply *m);
private:
+ /// check if we can throw out op from a disconnected client
+ bool op_is_discardable(class MOSDOp *m);
/// check if op has sufficient caps
bool op_has_sufficient_caps(PG *pg, class MOSDOp *m);
+ /// check if op should be (re)queued for processing
bool op_is_queueable(PG *pg, class MOSDOp *m);
+ /// check if subop should be (re)queued for processing
bool subop_is_queueable(PG *pg, class MOSDSubOp *m);
public: