]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: discard rank > 0 ops on erasure pools
authorSage Weil <sage@redhat.com>
Mon, 20 Oct 2014 20:55:33 +0000 (13:55 -0700)
committerSage Weil <sage@redhat.com>
Thu, 13 Nov 2014 01:14:20 +0000 (17:14 -0800)
Erasure pools do not support read from replica, so we should drop
any rank > 0 requests.

This fixes a bug where an erasure pool maps to [1,2,3], temporarily maps
to [-1,2,3], sends a request to osd.2, and then remaps back to [1,2,3].
Because the 0 shard never appears on osd.2, the request sits in the
waiting_for_pg map indefinitely and cases slow request warnings.
This problem does not come up on replicated pools because all instances of
the PG are created equal.

Fix by only considering role == 0 for erasure pools as a correct mapping.

Fixes: #9835
Signed-off-by: Sage Weil <sage@redhat.com>
src/osd/OSD.cc

index 2469f60ffb7a24c8dad8d31f713d03ca0ff6fcdd..dce5a7268709683f9be829d34b4a0b840336de75 100644 (file)
@@ -5882,7 +5882,8 @@ void OSD::advance_map(ObjectStore::Transaction& t, C_Contexts *tfin)
     vector<int> acting;
     int nrep = osdmap->pg_to_acting_osds(pgid.pgid, acting);
     int role = osdmap->calc_pg_role(whoami, acting, nrep);
-    if (role >= 0) {
+    const pg_pool_t *pi = osdmap->get_pg_pool(pgid.pool());
+    if (role == 0 || (role > 0 && !pi->is_erasure())) {
       ++p;  // still me
     } else {
       dout(10) << " discarding waiting ops for " << pgid << dendl;
@@ -7570,7 +7571,9 @@ void OSD::handle_op(OpRequestRef op)
   if (!pg) {
     dout(7) << "hit non-existent pg " << pgid << dendl;
 
-    if (osdmap->get_pg_acting_role(pgid.pgid, whoami) >= 0) {
+    const pg_pool_t *pi = osdmap->get_pg_pool(pgid.pool());
+    int role = osdmap->get_pg_acting_role(pgid.pgid, whoami);
+    if (role == 0 || (role > 0 && !pi->is_erasure())) {
       dout(7) << "we are valid target for op, waiting" << dendl;
       waiting_for_pg[pgid].push_back(op);
       op->mark_delayed("waiting for pg to exist locally");