]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
os/bluestore/KernelBlockDevice: sync write() method
authorSage Weil <sage@redhat.com>
Thu, 13 Apr 2017 14:29:26 +0000 (10:29 -0400)
committerSage Weil <sage@redhat.com>
Wed, 3 May 2017 15:23:01 +0000 (10:23 -0500)
Avoid aio machinery (and context switching) and do a simple
synchronous (O_DIRECT) write.

Signed-off-by: Sage Weil <sage@redhat.com>
src/os/bluestore/BlockDevice.h
src/os/bluestore/KernelDevice.cc
src/os/bluestore/KernelDevice.h
src/os/bluestore/NVMEDevice.cc
src/os/bluestore/NVMEDevice.h

index 157add61fcc11c1f2247a2fd5606586f302a1e34..d0ec9a1b462c419ddf414e482cd3d9d895cfb112 100644 (file)
@@ -108,6 +108,10 @@ public:
     uint64_t len,
     char *buf,
     bool buffered) = 0;
+  virtual int write(
+    uint64_t off,
+    bufferlist& bl,
+    bool buffered) = 0;
 
   virtual int aio_read(
     uint64_t off,
index 77eaf3602bc8b3e99c9975c01d4cfc181b63ae84..0041ec53a8b24ef774d7e74e788cc3912d70cfe3 100644 (file)
@@ -527,6 +527,66 @@ void KernelDevice::aio_submit(IOContext *ioc)
   }
 }
 
+int KernelDevice::_sync_write(uint64_t off, bufferlist &bl, bool buffered)
+{
+  uint64_t len = bl.length();
+  dout(5) << __func__ << " 0x" << std::hex << off << "~" << len
+         << std::dec << " buffered" << dendl;
+  if (cct->_conf->bdev_inject_crash &&
+      rand() % cct->_conf->bdev_inject_crash == 0) {
+    derr << __func__ << " bdev_inject_crash: dropping io 0x" << std::hex
+        << off << "~" << len << std::dec << dendl;
+    ++injecting_crash;
+    return 0;
+  }
+  vector<iovec> iov;
+  bl.prepare_iov(&iov);
+  int r = ::pwritev(buffered ? fd_buffered : fd_direct,
+                   &iov[0], iov.size(), off);
+
+  if (r < 0) {
+    r = -errno;
+    derr << __func__ << " pwritev error: " << cpp_strerror(r) << dendl;
+    return r;
+  }
+  if (buffered) {
+    // initiate IO (but do not wait)
+    r = ::sync_file_range(fd_buffered, off, len, SYNC_FILE_RANGE_WRITE);
+    if (r < 0) {
+      r = -errno;
+      derr << __func__ << " sync_file_range error: " << cpp_strerror(r) << dendl;
+      return r;
+    }
+  }
+  return 0;
+}
+
+int KernelDevice::write(
+  uint64_t off,
+  bufferlist &bl,
+  bool buffered)
+{
+  uint64_t len = bl.length();
+  dout(20) << __func__ << " 0x" << std::hex << off << "~" << len << std::dec
+          << (buffered ? " (buffered)" : " (direct)")
+          << dendl;
+  assert(off % block_size == 0);
+  assert(len % block_size == 0);
+  assert(len > 0);
+  assert(off < size);
+  assert(off + len <= size);
+
+  if ((!buffered || bl.get_num_buffers() >= IOV_MAX) &&
+      bl.rebuild_aligned_size_and_memory(block_size, block_size)) {
+    dout(20) << __func__ << " rebuilding buffer to be aligned" << dendl;
+  }
+  dout(40) << "data: ";
+  bl.hexdump(*_dout);
+  *_dout << dendl;
+
+  return _sync_write(off, bl, buffered);
+}
+
 int KernelDevice::aio_write(
   uint64_t off,
   bufferlist &bl,
@@ -581,35 +641,10 @@ int KernelDevice::aio_write(
   } else
 #endif
   {
-    dout(5) << __func__ << " 0x" << std::hex << off << "~" << len
-           << std::dec << " buffered" << dendl;
-    if (cct->_conf->bdev_inject_crash &&
-       rand() % cct->_conf->bdev_inject_crash == 0) {
-      derr << __func__ << " bdev_inject_crash: dropping io 0x" << std::hex
-          << off << "~" << len << std::dec << dendl;
-      ++injecting_crash;
-      return 0;
-    }
-    vector<iovec> iov;
-    bl.prepare_iov(&iov);
-    int r = ::pwritev(buffered ? fd_buffered : fd_direct,
-                     &iov[0], iov.size(), off);
+    int r = _sync_write(off, bl, buffered);
     _aio_log_finish(ioc, off, len);
-
-    if (r < 0) {
-      r = -errno;
-      derr << __func__ << " pwritev error: " << cpp_strerror(r) << dendl;
+    if (r < 0)
       return r;
-    }
-    if (buffered) {
-      // initiate IO (but do not wait)
-      r = ::sync_file_range(fd_buffered, off, len, SYNC_FILE_RANGE_WRITE);
-      if (r < 0) {
-        r = -errno;
-        derr << __func__ << " sync_file_range error: " << cpp_strerror(r) << dendl;
-        return r;
-      }
-    }
   }
   return 0;
 }
index 2cc2ebdccee9ae8810312867d27ef79daf4b244e..faccde3d5ba086c07140cfc894438a0c03d07c65 100644 (file)
@@ -60,6 +60,8 @@ class KernelDevice : public BlockDevice {
   void _aio_log_start(IOContext *ioc, uint64_t offset, uint64_t length);
   void _aio_log_finish(IOContext *ioc, uint64_t offset, uint64_t length);
 
+  int _sync_write(uint64_t off, bufferlist& bl, bool buffered);
+
   int _lock();
 
   int direct_read_unaligned(uint64_t off, uint64_t len, char *buf);
@@ -93,6 +95,7 @@ public:
               IOContext *ioc) override;
   int read_random(uint64_t off, uint64_t len, char *buf, bool buffered) override;
 
+  int write(uint64_t off, bufferlist& bl, bool buffered) override;
   int aio_write(uint64_t off, bufferlist& bl,
                IOContext *ioc,
                bool buffered) override;
index 0ffdff3dda55c03955922dd1b13f232c5a2fa2f1..e33e8bec36ffe2e0b29e678a9be9035b62b5326f 100644 (file)
@@ -1024,6 +1024,15 @@ int NVMEDevice::aio_write(
   return 0;
 }
 
+int NVMEDevice::write(uint64_t off, bufferlist &bl, bool buffered)
+{
+  // FIXME: there is presumably a more efficient way to do this...
+  IOContext ioc(NULL);
+  aio_write(off, bl, &ioc, buffered);
+  ioc.aio_wait();
+  return 0;
+}
+
 int NVMEDevice::read(uint64_t off, uint64_t len, bufferlist *pbl,
                      IOContext *ioc,
                      bool buffered)
index 318c3415a949ec37742901613dc02ebdbd915a41..f670e308e435602e8babaadefd27ba1352894112 100644 (file)
@@ -229,6 +229,7 @@ class NVMEDevice : public BlockDevice {
   int aio_write(uint64_t off, bufferlist& bl,
                 IOContext *ioc,
                 bool buffered) override;
+  int write(uint64_t off, bufferlist& bl, bool buffered) override;
   int flush() override;
   int read_random(uint64_t off, uint64_t len, char *buf, bool buffered) override;