]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
ECBackend: propogate read errors through callbacks
authorSamuel Just <sjust@redhat.com>
Mon, 21 Nov 2016 22:56:56 +0000 (14:56 -0800)
committerSamuel Just <sjust@redhat.com>
Mon, 21 Nov 2016 23:08:53 +0000 (15:08 -0800)
Signed-off-by: Samuel Just <sjust@redhat.com>
src/osd/ECBackend.cc
src/osd/ECBackend.h

index d078ca4cfae2b246e3c4d727814642dc0cf06e1a..9b66600c0f17dbc175a2b0b0af08d1e3740f3407 100644 (file)
@@ -1782,8 +1782,10 @@ bool ECBackend::try_state_to_reads()
   if (!op->remote_read.empty()) {
     objects_read_async_no_cache(
       op->remote_read,
-      [this, op](hobject_t::bitwisemap<extent_map> &&results) {
-       op->remote_read_result = std::move(results);
+      [this, op](hobject_t::bitwisemap<pair<int, extent_map> > &&results) {
+       for (auto &&i: results) {
+         op->remote_read_result.emplace(i.first, i.second.second);
+       }
        check_ops();
       });
   }
@@ -2056,7 +2058,7 @@ void ECBackend::objects_read_async(
        hoid(hoid),
        to_read(to_read),
        on_complete(on_complete) {}
-    void operator()(hobject_t::bitwisemap<extent_map> &&results) {
+    void operator()(hobject_t::bitwisemap<pair<int, extent_map> > &&results) {
       auto dpp = ec->get_parent()->get_dpp();
       ldpp_dout(dpp, 20) << "objects_read_async_cb: got: " << results
                         << dendl;
@@ -2065,28 +2067,37 @@ void ECBackend::objects_read_async(
 
       auto &got = results[hoid];
 
+      int r = 0;
       for (auto &&read: to_read) {
-       assert(read.second.first);
-       uint64_t offset = read.first.get<0>();
-       uint64_t length = read.first.get<1>();
-       auto range = got.get_containing_range(offset, length);
-       assert(range.first != range.second);
-       assert(range.first.get_off() <= offset);
-       assert(
-         (offset + length) <=
-         (range.first.get_off() + range.first.get_len()));
-       read.second.first->substr_of(
-         range.first.get_val(),
-         offset - range.first.get_off(),
-         length);
-       if (read.second.second) {
-         read.second.second->complete(length);
-         read.second.second = nullptr;
+       if (got.first < 0) {
+         if (read.second.second) {
+           read.second.second->complete(got.first);
+         }
+         if (r == 0)
+           r = got.first;
+       } else {
+         assert(read.second.first);
+         uint64_t offset = read.first.get<0>();
+         uint64_t length = read.first.get<1>();
+         auto range = got.second.get_containing_range(offset, length);
+         assert(range.first != range.second);
+         assert(range.first.get_off() <= offset);
+         assert(
+           (offset + length) <=
+           (range.first.get_off() + range.first.get_len()));
+         read.second.first->substr_of(
+           range.first.get_val(),
+           offset - range.first.get_off(),
+           length);
+         if (read.second.second) {
+           read.second.second->complete(length);
+           read.second.second = nullptr;
+         }
        }
       }
       to_read.clear();
       if (on_complete) {
-       on_complete.release()->complete(0);
+       on_complete.release()->complete(r);
       }
     }
     ~cb() {
@@ -2099,11 +2110,12 @@ void ECBackend::objects_read_async(
   objects_read_and_reconstruct(
     reads,
     fast_read,
-    make_gen_lambda_context<hobject_t::bitwisemap<extent_map> &&, cb>(
-      cb(this,
-        hoid,
-        to_read,
-        on_complete)));
+    make_gen_lambda_context<
+      hobject_t::bitwisemap<pair<int, extent_map> > &&, cb>(
+       cb(this,
+          hoid,
+          to_read,
+          on_complete)));
 }
 
 struct CallClientContexts :
@@ -2160,7 +2172,7 @@ struct CallClientContexts :
       res.returned.pop_front();
     }
 out:
-    status->complete_object(hoid, std::move(result));
+    status->complete_object(hoid, res.r, std::move(result));
     ec->kick_reads();
   }
 };
@@ -2170,7 +2182,7 @@ void ECBackend::objects_read_and_reconstruct(
     std::list<boost::tuple<uint64_t, uint64_t, uint32_t> >
   > &reads,
   bool fast_read,
-  GenContextURef<hobject_t::bitwisemap<extent_map> &&> &&func)
+  GenContextURef<hobject_t::bitwisemap<pair<int, extent_map> > &&> &&func)
 {
   in_progress_client_reads.emplace_back(
     reads.size(), std::move(func));
index dcc02a348c23322251037fcaee0d06ba40e9e086..3c9e0f2a2ca759cdf9976b31010a95b7916bde85 100644 (file)
@@ -141,24 +141,25 @@ public:
       std::list<boost::tuple<uint64_t, uint64_t, uint32_t> >
     > &reads,
     bool fast_read,
-    GenContextURef<hobject_t::bitwisemap<extent_map> &&> &&func);
+    GenContextURef<hobject_t::bitwisemap<pair<int, extent_map> > &&> &&func);
 
   friend struct CallClientContexts;
   struct ClientAsyncReadStatus {
     unsigned objects_to_read;
-    GenContextURef<hobject_t::bitwisemap<extent_map> &&> func;
-    hobject_t::bitwisemap<extent_map> results;
+    GenContextURef<hobject_t::bitwisemap<pair<int, extent_map> > &&> func;
+    hobject_t::bitwisemap<pair<int, extent_map> > results;
     explicit ClientAsyncReadStatus(
       unsigned objects_to_read,
-      GenContextURef<hobject_t::bitwisemap<extent_map> &&> &&func)
+      GenContextURef<hobject_t::bitwisemap<pair<int, extent_map> > &&> &&func)
       : objects_to_read(objects_to_read), func(std::move(func)) {}
     void complete_object(
       const hobject_t &hoid,
+      int err,
       extent_map &&buffers) {
       assert(objects_to_read);
       --objects_to_read;
       assert(!results.count(hoid));
-      results.emplace(hoid, std::move(buffers));
+      results.emplace(hoid, make_pair(err, std::move(buffers)));
     }
     bool is_complete() const {
       return objects_to_read == 0;
@@ -190,8 +191,9 @@ public:
     objects_read_and_reconstruct(
       _to_read,
       false,
-      make_gen_lambda_context<hobject_t::bitwisemap<extent_map> &&, Func>(
-       std::forward<Func>(on_complete)));
+      make_gen_lambda_context<
+        hobject_t::bitwisemap<pair<int, extent_map> > &&, Func>(
+         std::forward<Func>(on_complete)));
   }
   void kick_reads() {
     while (in_progress_client_reads.size() &&