]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd/ECBackend: preserve requests for other objects when sending extra reads
authorJosh Durgin <jdurgin@redhat.com>
Fri, 20 Apr 2018 22:42:56 +0000 (18:42 -0400)
committerJosh Durgin <jdurgin@redhat.com>
Fri, 20 Apr 2018 23:42:15 +0000 (19:42 -0400)
When multiple objects are in flight for the same ReadOp, swap() on the
map<hobject_t, read_request_t> would remove requests for all objects.

We just want to replace the requests for the single object we're
dealing with in send_all_remaining_reads().

This prevents crashing trying to look up rop.to_read[hoid] when another
object in the same ReadOp gets an EIO and tries to send more requests.

Test this by using osd-recovery-max-single-start to bundle multiple
reads into one ReadOp. Save and restore CEPH_ARGS so custom settings
are reset for each test.

Fixes: http://tracker.ceph.com/issues/23195 (the 2nd crash there)
Signed-off-by: Josh Durgin <jdurgin@redhat.com>
qa/standalone/erasure-code/test-erasure-eio.sh
src/osd/ECBackend.cc

index 0b7a5b3a7526cf24da08d34a4ad0db6968400ad5..309df13340cf74ac4ef18dba3098f054fb01dee8 100755 (executable)
@@ -419,9 +419,10 @@ function TEST_ec_recovery_multiple_objects() {
     local dir=$1
     local objname=myobject
 
-    export CEPH_ARGS
+    ORIG_ARGS=$CEPH_ARGS
     CEPH_ARGS+=' --osd-recovery-max-single-start 3 --osd-recovery-max-active 3 '
     setup_osds 7 || return 1
+    CEPH_ARGS=$ORIG_ARGS
 
     local poolname=pool-jerasure
     create_erasure_coded_pool $poolname 3 2 || return 1
@@ -447,9 +448,10 @@ function TEST_ec_recovery_multiple_objects_eio() {
     local dir=$1
     local objname=myobject
 
-    export CEPH_ARGS
+    ORIG_ARGS=$CEPH_ARGS
     CEPH_ARGS+=' --osd-recovery-max-single-start 3 --osd-recovery-max-active 3 '
     setup_osds 7 || return 1
+    CEPH_ARGS=$ORIG_ARGS
 
     local poolname=pool-jerasure
     create_erasure_coded_pool $poolname 3 2 || return 1
@@ -480,9 +482,10 @@ function TEST_ec_backfill_unfound() {
     # Must be between 1 and $lastobj
     local testobj=obj250
 
-    export CEPH_ARGS
+    ORIG_ARGS=$CEPH_ARGS
     CEPH_ARGS+=' --osd_min_pg_log_entries=5 --osd_max_pg_log_entries=10'
     setup_osds 5 || return 1
+    CEPH_ARGS=$ORIG_ARGS
 
     local poolname=pool-jerasure
     create_erasure_coded_pool $poolname 3 2 || return 1
@@ -558,7 +561,11 @@ function TEST_ec_recovery_unfound() {
     # Must be between 1 and $lastobj
     local testobj=obj75
 
+    ORIG_ARGS=$CEPH_ARGS
+    CEPH_ARGS+=' --osd-recovery-max-single-start 3 --osd-recovery-max-active 3 '
+    CEPH_ARGS+=' --osd_min_pg_log_entries=5 --osd_max_pg_log_entries=10'
     setup_osds 5 || return 1
+    CEPH_ARGS=$ORIG_ARGS
 
     local poolname=pool-jerasure
     create_erasure_coded_pool $poolname 3 2 || return 1
index 8efdb4f39a4d8f7263109f0fe0955f43140752b4..7302c3522849bd521239d33ba422012dc9c51b7f 100644 (file)
@@ -2337,17 +2337,14 @@ int ECBackend::send_all_remaining_reads(
   GenContext<pair<RecoveryMessages *, read_result_t& > &> *c =
     rop.to_read.find(hoid)->second.cb;
 
-  map<hobject_t, read_request_t> for_read_op;
-  for_read_op.insert(
-    make_pair(
+  rop.to_read.erase(hoid);
+  rop.to_read.insert(make_pair(
       hoid,
       read_request_t(
        offsets,
        shards,
        false,
        c)));
-
-  rop.to_read.swap(for_read_op);
   do_read_op(rop);
   return 0;
 }