]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: do not proxy reads unless all OSDs proxy features too
authorSage Weil <sage@redhat.com>
Mon, 16 Feb 2015 22:18:40 +0000 (14:18 -0800)
committerSage Weil <sage@redhat.com>
Mon, 23 Feb 2015 18:10:54 +0000 (10:10 -0800)
Specifically, the object_copy_data_t encoding changed such that the reply
encoding is dependent on features; if we proxy such a read to an old
OSD it will use *our* features to encode instead of the original OSD's.

This effectively conditionally reverts 8e145e08ede625adfb5d41216d7777d6c9707bd0
when the cluster features aren't all present.

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

index 3886f32fa5a5ee323e3c3c925ff0c9e07f1eec7d..95f7f2b6463e1fd162bf9b61e43431c3238014db 100644 (file)
@@ -1840,13 +1840,23 @@ bool ReplicatedPG::maybe_handle_cache(OpRequestRef op,
     return true;
   }
 
+  // older versions do not proxy the feature bits.
+  bool can_proxy_read = get_osdmap()->get_up_osd_features() &
+    CEPH_FEATURE_OSD_PROXY_FEATURES;
+  OpRequestRef promote_op;
+
   switch (pool.info.cache_mode) {
   case pg_pool_t::CACHEMODE_WRITEBACK:
     if (agent_state &&
        agent_state->evict_mode == TierAgentState::EVICT_MODE_FULL) {
       if (!op->may_write() && !op->may_cache() && !write_ordered) {
-       dout(20) << __func__ << " cache pool full, proxying read" << dendl;
-       do_proxy_read(op);
+       if (can_proxy_read) {
+         dout(20) << __func__ << " cache pool full, proxying read" << dendl;
+         do_proxy_read(op);
+       } else {
+         dout(20) << __func__ << " cache pool full, redirect read" << dendl;
+         do_cache_redirect(op);
+       }
        return true;
       }
       dout(20) << __func__ << " cache pool full, waiting" << dendl;
@@ -1861,8 +1871,10 @@ bool ReplicatedPG::maybe_handle_cache(OpRequestRef op,
       return true;
     }
 
-    // Always proxy
-    do_proxy_read(op);
+    if (can_proxy_read)
+      do_proxy_read(op);
+    else
+      promote_op = op;   // for non-proxy case promote_object needs this
 
     // Avoid duplicate promotion
     if (obc.get() && obc->is_blocked()) {
@@ -1872,17 +1884,19 @@ bool ReplicatedPG::maybe_handle_cache(OpRequestRef op,
     // Promote too?
     switch (pool.info.min_read_recency_for_promote) {
     case 0:
-      promote_object(obc, missing_oid, oloc, OpRequestRef());
+      promote_object(obc, missing_oid, oloc, promote_op);
       break;
     case 1:
       // Check if in the current hit set
       if (in_hit_set) {
-       promote_object(obc, missing_oid, oloc, OpRequestRef());
+       promote_object(obc, missing_oid, oloc, promote_op);
+      } else if (!can_proxy_read) {
+       do_cache_redirect(op);
       }
       break;
     default:
       if (in_hit_set) {
-       promote_object(obc, missing_oid, oloc, OpRequestRef());
+       promote_object(obc, missing_oid, oloc, promote_op);
       } else {
        // Check if in other hit sets
        map<time_t,HitSetRef>::iterator itor;
@@ -1894,7 +1908,9 @@ bool ReplicatedPG::maybe_handle_cache(OpRequestRef op,
          }
        }
        if (in_other_hit_sets) {
-         promote_object(obc, missing_oid, oloc, OpRequestRef());
+         promote_object(obc, missing_oid, oloc, promote_op);
+       } else if (!can_proxy_read) {
+         do_cache_redirect(op);
        }
       }
       break;