]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: fix/simplify op discard checks
authorSage Weil <sage.weil@dreamhost.com>
Tue, 25 Oct 2011 05:21:43 +0000 (22:21 -0700)
committerSage Weil <sage.weil@dreamhost.com>
Tue, 25 Oct 2011 05:21:43 +0000 (22:21 -0700)
Use a helper to determine when we should discard an op due to the client
being disconnected.  Use this when the op is first received, (re)queued,
and dequeued.

Fix the check to keep ops that are replayed ACKs, as we should make every
effort to reapply those even when the client goes away.

Signed-off-by: Sage Weil <sage.weil@dreamhost.com>
src/osd/OSD.cc
src/osd/OSD.h

index 829f3e79b2d7a4e2b6fbcf7d20d3d55d115fd8fe..9595c204bec267453cf0549ebad98f34d0b6c1b5 100644 (file)
@@ -5145,9 +5145,7 @@ void OSD::handle_misdirected_op(PG *pg, MOSDOp *op)
 
 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;
   }
@@ -5330,6 +5328,20 @@ void OSD::handle_sub_op_reply(MOSDSubOpReply *op)
   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.
  */
@@ -5342,6 +5354,11 @@ bool OSD::op_is_queueable(PG *pg, MOSDOp *op)
     return false;
   }
 
+  if (op_is_discardable(op)) {
+    op->put();
+    return false;
+  }
+
   // misdirected?
   if (op->may_write()) {
     if (!pg->is_primary() ||
@@ -5488,20 +5505,17 @@ void OSD::dequeue_op(PG *pg)
   }
   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
index 1cd083bd65052f51cae12484e1f48ede530c3e81..86efcc896182e4e438cb3a962eda109a11ea9b46 100644 (file)
@@ -1092,9 +1092,13 @@ public:
   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: