]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: convert read_buffered() to read_random() with buffered flag
authorJianjian Huo <jianjian.huo@ssi.samsung.com>
Thu, 19 May 2016 22:03:41 +0000 (15:03 -0700)
committerJianjian Huo <jianjian.huo@ssi.samsung.com>
Tue, 7 Jun 2016 01:11:30 +0000 (18:11 -0700)
New function will handle unaligned random read for both buffered or
direct read.

Signed-off-by: Jianjian Huo <jianjian.huo@ssi.samsung.com>
src/os/bluestore/BlockDevice.h
src/os/bluestore/BlueFS.cc
src/os/bluestore/KernelDevice.cc
src/os/bluestore/KernelDevice.h
src/os/bluestore/NVMEDevice.cc
src/os/bluestore/NVMEDevice.h

index 6ccc79dc9d5ef76c858be2244530c38774b2b25b..f3ba54af4fbfebf7915d63547370dddf9b24d647 100644 (file)
@@ -93,7 +93,8 @@ public:
 
   virtual int read(uint64_t off, uint64_t len, bufferlist *pbl,
           IOContext *ioc, bool buffered) = 0;
-  virtual int read_buffered(uint64_t off, uint64_t len, char *buf) = 0;
+  virtual int read_random(uint64_t off, uint64_t len, char *buf,
+           bool buffered) = 0;
 
   virtual int aio_write(uint64_t off, bufferlist& bl,
                IOContext *ioc, bool buffered) = 0;
index d8ed6e1d94bc87cc6bb33ec13afc54bdf6f96628..ff1dc71b94475cc5c14a9de1d5c48c8cccbefd7e 100644 (file)
@@ -738,7 +738,7 @@ int BlueFS::_read_random(
     }
     dout(20) << __func__ << " read buffered " << x_off << "~" << l << " of "
               << *p << dendl;
-    int r = bdev[p->bdev]->read_buffered(p->offset + x_off, l, out);
+    int r = bdev[p->bdev]->read_random(p->offset + x_off, l, out, true);
     assert(r == 0);
     off += l;
     len -= l;
index 5e4d563a29cc5d53ff78588bc68d683a861c2777..2302633ad755652fc00f1de40b7c73988d5b84ed 100644 (file)
@@ -25,6 +25,7 @@
 #include "common/errno.h"
 #include "common/debug.h"
 #include "common/blkdev.h"
+#include "common/align.h"
 
 #define dout_subsys ceph_subsys_bdev
 #undef dout_prefix
@@ -495,26 +496,69 @@ int KernelDevice::read(uint64_t off, uint64_t len, bufferlist *pbl,
   return r < 0 ? r : 0;
 }
 
-int KernelDevice::read_buffered(uint64_t off, uint64_t len, char *buf)
+int KernelDevice::direct_read_unaligned(uint64_t off, uint64_t len, char *buf)
+{
+  uint64_t aligned_off = align_down(off, block_size);
+  uint64_t aligned_len = align_up(off+len, block_size) - aligned_off;
+  bufferptr p = buffer::create_page_aligned(aligned_len);
+  int r = 0;
+
+  r = ::pread(fd_direct, p.c_str(), aligned_len, aligned_off);
+  if (r < 0) {
+    r = -errno;
+    goto out;
+  }
+  assert((uint64_t)r == aligned_len);
+  memcpy(buf, p.c_str() + (off - aligned_off), len);
+
+  dout(40) << __func__ << " data: ";
+  bufferlist bl;
+  bl.append(buf, len);
+  bl.hexdump(*_dout);
+  *_dout << dendl;
+
+ out:
+  return r < 0 ? r : 0;
+}
+
+int KernelDevice::read_random(uint64_t off, uint64_t len, char *buf,
+                       bool buffered)
 {
   dout(5) << __func__ << " 0x" << std::hex << off << "~" << len << std::dec
          << dendl;
   assert(len > 0);
   assert(off < size);
   assert(off + len <= size);
-
   int r = 0;
-  char *t = buf;
-  uint64_t left = len;
-  while (left > 0) {
-    r = ::pread(fd_buffered, t, left, off);
+
+  //if it's direct io and unaligned, we have to use a internal buffer
+  if (!buffered && ((off % block_size != 0)
+                    || (len % block_size != 0)
+                    || (uintptr_t(buf) % CEPH_PAGE_SIZE != 0)))
+    return direct_read_unaligned(off, len, buf);
+
+  if (buffered) {
+    //buffered read
+    char *t = buf;
+    uint64_t left = len;
+    while (left > 0) {
+      r = ::pread(fd_buffered, t, left, off);
+      if (r < 0) {
+       r = -errno;
+       goto out;
+      }
+      off += r;
+      t += r;
+      left -= r;
+    }
+  } else {
+    //direct and aligned read
+    r = ::pread(fd_direct, buf, len, off);
     if (r < 0) {
       r = -errno;
       goto out;
     }
-    off += r;
-    t += r;
-    left -= r;
+    assert((uint64_t)r == len);
   }
 
   dout(40) << __func__ << " data: ";
index 0a1cc36a7af822edaa1104397c36f62b0634ef35..48cb0d44d93d0ddf8a89a12937fd02ac3f10ac0d 100644 (file)
@@ -62,6 +62,8 @@ class KernelDevice : public BlockDevice {
 
   int _lock();
 
+  int direct_read_unaligned(uint64_t off, uint64_t len, char *buf);
+
 public:
   KernelDevice(aio_callback_t cb, void *cbpriv);
 
@@ -77,7 +79,7 @@ public:
   int read(uint64_t off, uint64_t len, bufferlist *pbl,
           IOContext *ioc,
           bool buffered) override;
-  int read_buffered(uint64_t off, uint64_t len, char *buf) override;
+  int read_random(uint64_t off, uint64_t len, char *buf, bool buffered) override;
 
   int aio_write(uint64_t off, bufferlist& bl,
                IOContext *ioc,
index 71667549f047abc5fed633f56d718d3b151cf584..c5ba1e48086448718a05661c8c7e3bcc4c42be3c 100644 (file)
@@ -938,7 +938,7 @@ int NVMEDevice::read(uint64_t off, uint64_t len, bufferlist *pbl,
   return r;
 }
 
-int NVMEDevice::read_buffered(uint64_t off, uint64_t len, char *buf)
+int NVMEDevice::read_random(uint64_t off, uint64_t len, char *buf, bool buffered)
 {
   assert(len > 0);
   assert(off < size);
index 62294def241d23c46d130beb9f60990967a66bd3..75b751ae533d9c0cd462567da5803c2ad1d86956 100644 (file)
@@ -228,7 +228,7 @@ class NVMEDevice : public BlockDevice {
                 IOContext *ioc,
                 bool buffered) override;
   int flush() override;
-  int read_buffered(uint64_t off, uint64_t len, char *buf) override;
+  int read_random(uint64_t off, uint64_t len, char *buf, bool buffered) override;
 
   // for managing buffered readers/writers
   int invalidate_cache(uint64_t off, uint64_t len) override;