]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore: deal with scenarios in which bufferlist of do_writev has more... 43537/head
authorXuehan Xu <xxhdx1985126@gmail.com>
Thu, 14 Oct 2021 09:43:23 +0000 (17:43 +0800)
committerXuehan Xu <xxhdx1985126@gmail.com>
Fri, 15 Oct 2021 10:08:47 +0000 (18:08 +0800)
Signed-off-by: Xuehan Xu <xxhdx1985126@gmail.com>
src/crimson/os/seastore/segment_manager/block.cc

index 5b395fac589b63ef8263c43c81f2f1c96e0e8d3d..2fb9e4e41931cd57cd0d33c63c953615d59c4a57 100644 (file)
@@ -5,6 +5,7 @@
 #include <string.h>
 
 #include "crimson/common/config_proxy.h"
+#include "crimson/common/errorator-loop.h"
 #include "crimson/common/log.h"
 
 #include "include/buffer.h"
@@ -53,31 +54,43 @@ static write_ertr::future<> do_writev(
   size_t block_size)
 {
   logger().debug(
-    "block: do_writev offset {} len {}",
+    "block: do_writev offset {} len {}, {} buffers",
     offset,
-    bl.length());
+    bl.length(),
+    bl.get_num_buffers());
 
   // writev requires each buffer to be aligned to the disks' block
   // size, we need to rebuild here
   bl.rebuild_aligned(block_size);
 
-  std::vector<iovec> iov;
-  bl.prepare_iov(&iov);
-  return device.dma_write(
-    offset,
-    std::move(iov)
-  ).handle_exception([](auto e) -> write_ertr::future<size_t> {
-      logger().error(
-       "do_writev: dma_write got error {}",
-       e);
-      return crimson::ct_error::input_output_error::make();
-  }).then(
-    [bl=std::move(bl)/* hold the buf until the end of io */](size_t written)
-              -> write_ertr::future<> {
-    if (written != bl.length()) {
-      return crimson::ct_error::input_output_error::make();
-    }
-    return write_ertr::now();
+  return seastar::do_with(
+    bl.prepare_iovs(),
+    std::move(bl),
+    [&device, offset] (auto& iovs, auto& bl) {
+    return write_ertr::parallel_for_each(
+      iovs,
+      [&device, offset](auto& p) mutable {
+      auto off = offset + p.first.first;
+      auto len = p.first.second;
+      auto& iov = p.second;
+      logger().debug("do_writev: dma_write to {}, length {}", off, len);
+      return device.dma_write(off, std::move(iov))
+      .handle_exception([](auto e) -> write_ertr::future<size_t> {
+       logger().error(
+         "do_writev: dma_write got error {}",
+         e);
+       return crimson::ct_error::input_output_error::make();
+      }).then(
+       [off, len](size_t written) -> write_ertr::future<> {
+       if (written != len) {
+         logger().error(
+           "do_writev: dma_write to {}, failed, written {} != iov len {}",
+           off, written, len);
+         return crimson::ct_error::input_output_error::make();
+       }
+       return write_ertr::now();
+      });
+    });
   });
 }
 
@@ -96,7 +109,12 @@ static read_ertr::future<> do_read(
     offset,
     bptr.c_str(),
     len
-  ).handle_exception([](auto e) -> read_ertr::future<size_t> {
+  ).handle_exception(
+    //FIXME: this is a little bit tricky, since seastar::future<T>::handle_exception
+    // returns seastar::future<T>, to return an crimson::ct_error, we have to create
+    // a seastar::future<T> holding that crimson::ct_error. This is not necessary
+    // once seastar::future<T>::handle_exception() returns seastar::futurize_t<T>
+    [](auto e) -> read_ertr::future<size_t> {
     logger().error(
       "do_read: dma_read got error {}",
       e);