]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: BlueFS support write_life_time feature of SSD.
authorJianpeng Ma <jianpeng.ma@intel.com>
Thu, 1 Nov 2018 08:10:56 +0000 (16:10 +0800)
committerJianpeng Ma <jianpeng.ma@intel.com>
Thu, 1 Nov 2018 08:10:56 +0000 (16:10 +0800)
Rocksdb already supported this feature for posix fs backend.

Signed-off-by: Jianpeng Ma <jianpeng.ma@intel.com>
src/os/bluestore/BlockDevice.h
src/os/bluestore/BlueFS.cc
src/os/bluestore/BlueFS.h
src/os/bluestore/BlueRocksEnv.cc
src/os/bluestore/KernelDevice.cc
src/os/bluestore/KernelDevice.h
src/os/bluestore/NVMEDevice.cc
src/os/bluestore/NVMEDevice.h
src/os/bluestore/PMEMDevice.cc
src/os/bluestore/PMEMDevice.h

index d2da92212b6df2b7c5e2bbc330327ae5acdbf7eb..5faa26073bafe8a9068f36100c0892e2e60509e0 100644 (file)
 #include "include/interval_set.h"
 #define SPDK_PREFIX "spdk:"
 
+#if !defined(F_SET_FILE_RW_HINT)
+#define F_LINUX_SPECIFIC_BASE 1024
+#define F_SET_FILE_RW_HINT         (F_LINUX_SPECIFIC_BASE + 14)
+#endif
+
+// These values match Linux definition
+// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/fcntl.h#n56
+#define  WRITE_LIFE_NOT_SET    0       // No hint information set
+#define  WRITE_LIFE_NONE       1       // No hints about write life time
+#define  WRITE_LIFE_SHORT      2       // Data written has a short life time
+#define  WRITE_LIFE_MEDIUM     3       // Data written has a medium life time
+#define  WRITE_LIFE_LONG       4       // Data written has a long life time
+#define  WRITE_LIFE_EXTREME    5       // Data written has an extremely long life time
+#define  WRITE_LIFE_MAX        6
+
 class CephContext;
 
 /// track in-flight io
@@ -170,7 +185,8 @@ public:
   virtual int write(
     uint64_t off,
     bufferlist& bl,
-    bool buffered) = 0;
+    bool buffered,
+    int write_hint = WRITE_LIFE_NOT_SET) = 0;
 
   virtual int aio_read(
     uint64_t off,
@@ -181,7 +197,8 @@ public:
     uint64_t off,
     bufferlist& bl,
     IOContext *ioc,
-    bool buffered) = 0;
+    bool buffered,
+    int write_hint = WRITE_LIFE_NOT_SET) = 0;
   virtual int flush() = 0;
   virtual int discard(uint64_t offset, uint64_t len) { return 0; }
   virtual int queue_discard(interval_set<uint64_t> &to_release) { return -1; }
index 7c9160fcc197e601c60e485ad6a05fd8a2ab03a6..f5b1296fa888c7658fb30d214b23c8c8914664e2 100644 (file)
@@ -2163,9 +2163,9 @@ int BlueFS::_flush_range(FileWriter *h, uint64_t offset, uint64_t length)
       }
     }
     if (cct->_conf->bluefs_sync_write) {
-      bdev[p->bdev]->write(p->offset + x_off, t, buffered);
+      bdev[p->bdev]->write(p->offset + x_off, t, buffered, h->write_hint);
     } else {
-      bdev[p->bdev]->aio_write(p->offset + x_off, t, h->iocv[p->bdev], buffered);
+      bdev[p->bdev]->aio_write(p->offset + x_off, t, h->iocv[p->bdev], buffered, h->write_hint);
     }
     h->dirty_devs[p->bdev] = true;
     if (p->bdev == BDEV_SLOW) {
index 3f555c2a4980d53d2af51037e317d639537bd27e..dd219d51d08c0e9646ad509bb4735a1b7b6ebecf 100644 (file)
@@ -126,6 +126,7 @@ public:
     bufferlist tail_block;  ///< existing partial block at end of file, if any
     bufferlist::page_aligned_appender buffer_appender;  //< for const char* only
     int writer_type = 0;    ///< WRITER_*
+    int write_hint = WRITE_LIFE_NOT_SET;
 
     ceph::mutex lock = ceph::make_mutex("BlueFS::FileWriter::lock");
     std::array<IOContext*,MAX_BDEV> iocv; ///< for each bdev
index f665f496a36882f07e137b4fd444f8715f4108f9..70d2d162bca4fa013ed85ad2a55c4206ec663226 100644 (file)
@@ -227,6 +227,10 @@ class BlueRocksWritableFile : public rocksdb::WritableFile {
     return false;
   }
 
+  void SetWriteLifeTimeHint(rocksdb::Env::WriteLifeTimeHint hint) override {
+    h->write_hint = (const int)hint;
+  }
+
   /*
    * Get the size of valid data in the file.
    */
index f7a9854bb29b5955ba4d53439708a927362c8775..219266a57464d1b5c5b6d48f929e767ab44c9c96 100644 (file)
@@ -34,8 +34,6 @@
 
 KernelDevice::KernelDevice(CephContext* cct, aio_callback_t cb, void *cbpriv, aio_callback_t d_cb, void *d_cbpriv)
   : BlockDevice(cct, cb, cbpriv),
-    fd_direct(-1),
-    fd_buffered(-1),
     aio(false), dio(false),
     aio_queue(cct->_conf->bdev_aio_max_queue_depth),
     discard_callback(d_cb),
@@ -47,6 +45,8 @@ KernelDevice::KernelDevice(CephContext* cct, aio_callback_t cb, void *cbpriv, ai
     discard_thread(this),
     injecting_crash(0)
 {
+  fd_directs.resize(WRITE_LIFE_MAX, -1);
+  fd_buffereds.resize(WRITE_LIFE_MAX, -1);
 }
 
 int KernelDevice::_lock()
@@ -55,7 +55,7 @@ int KernelDevice::_lock()
   memset(&l, 0, sizeof(l));
   l.l_type = F_WRLCK;
   l.l_whence = SEEK_SET;
-  int r = ::fcntl(fd_direct, F_SETLK, &l);
+  int r = ::fcntl(fd_directs[WRITE_LIFE_NOT_SET], F_SETLK, &l);
   if (r < 0)
     return -errno;
   return 0;
@@ -64,23 +64,45 @@ int KernelDevice::_lock()
 int KernelDevice::open(const string& p)
 {
   path = p;
-  int r = 0;
+  int r = 0, i = 0;
   dout(1) << __func__ << " path " << path << dendl;
 
-  fd_direct = ::open(path.c_str(), O_RDWR | O_DIRECT | O_CLOEXEC);
-  BlkDev blkdev_direct(fd_direct);
-  if (fd_direct < 0) {
-    r = -errno;
-    derr << __func__ << " open got: " << cpp_strerror(r) << dendl;
-    return r;
+  for (i = 0; i < WRITE_LIFE_MAX; i++) {
+    int fd = ::open(path.c_str(), O_RDWR | O_DIRECT);
+    if (fd  < 0) {
+      r = -errno;
+      break;
+    }
+    fd_directs[i] = fd;
+
+    fd  = ::open(path.c_str(), O_RDWR | O_CLOEXEC);
+    if (fd  < 0) {
+      r = -errno;
+      break;
+    }
+    fd_buffereds[i] = fd;
   }
-  fd_buffered = ::open(path.c_str(), O_RDWR | O_CLOEXEC);
-  BlkDev blkdev_buffered(fd_buffered);
-  if (fd_buffered < 0) {
-    r = -errno;
+
+  if (i != WRITE_LIFE_MAX) {
     derr << __func__ << " open got: " << cpp_strerror(r) << dendl;
-    goto out_direct;
+    goto out_fail;
+  }
+
+  for (i = WRITE_LIFE_NONE; i < WRITE_LIFE_MAX; i++) {
+    if (fcntl(fd_directs[i], F_SET_FILE_RW_HINT, &i) < 0) {
+      r = -errno;
+      break;
+    }
+    if (fcntl(fd_buffereds[i], F_SET_FILE_RW_HINT, &i) < 0) {
+      r = -errno;
+      break;
+    }
+  }
+  if (i != WRITE_LIFE_MAX) {
+    enable_wrt = false;
+    dout(0) << "ioctl(F_SET_FILE_RW_HINT) on " << path << " failed: " << cpp_strerror(r) << dendl;
   }
+
   dio = true;
   aio = cct->_conf->bdev_aio;
   if (!aio) {
@@ -89,7 +111,7 @@ int KernelDevice::open(const string& p)
 
   // disable readahead as it will wreak havoc on our mix of
   // directio/aio and buffered io.
-  r = posix_fadvise(fd_buffered, 0, 0, POSIX_FADV_RANDOM);
+  r = posix_fadvise(fd_buffereds[WRITE_LIFE_NOT_SET], 0, 0, POSIX_FADV_RANDOM);
   if (r) {
     r = -r;
     derr << __func__ << " open got: " << cpp_strerror(r) << dendl;
@@ -104,7 +126,7 @@ int KernelDevice::open(const string& p)
   }
 
   struct stat st;
-  r = ::fstat(fd_direct, &st);
+  r = ::fstat(fd_directs[WRITE_LIFE_NOT_SET], &st);
   if (r < 0) {
     r = -errno;
     derr << __func__ << " fstat got " << cpp_strerror(r) << dendl;
@@ -122,23 +144,27 @@ int KernelDevice::open(const string& p)
            << block_size << " anyway" << dendl;
   }
 
-  if (S_ISBLK(st.st_mode)) {
-    int64_t s;
-    r = blkdev_direct.get_size(&s);
-    if (r < 0) {
-      goto out_fail;
-    }
-    size = s;
-  } else {
-    size = st.st_size;
-  }
 
   {
+    BlkDev blkdev_direct(fd_directs[WRITE_LIFE_NOT_SET]);
+    BlkDev blkdev_buffered(fd_buffereds[WRITE_LIFE_NOT_SET]);
+
+    if (S_ISBLK(st.st_mode)) {
+      int64_t s;
+      r = blkdev_direct.get_size(&s);
+      if (r < 0) {
+       goto out_fail;
+      }
+      size = s;
+    } else {
+      size = st.st_size;
+    }
+
     char partition[PATH_MAX], devname[PATH_MAX];
     if ((r = blkdev_buffered.partition(partition, PATH_MAX)) ||
        (r = blkdev_buffered.wholedisk(devname, PATH_MAX))) {
       derr << "unable to get device name for " << path << ": "
-          << cpp_strerror(r) << dendl;
+       << cpp_strerror(r) << dendl;
       rotational = true;
     } else {
       dout(20) << __func__ << " devname " << devname << dendl;
@@ -169,12 +195,21 @@ int KernelDevice::open(const string& p)
          << dendl;
   return 0;
 
- out_fail:
-  VOID_TEMP_FAILURE_RETRY(::close(fd_buffered));
-  fd_buffered = -1;
- out_direct:
-  VOID_TEMP_FAILURE_RETRY(::close(fd_direct));
-  fd_direct = -1;
+out_fail:
+  for (i = 0; i < WRITE_LIFE_MAX; i++) {
+    if (fd_directs[i] >= 0) {
+      VOID_TEMP_FAILURE_RETRY(::close(fd_directs[i]));
+      fd_directs[i] = -1;
+    } else {
+      break;
+    }
+    if (fd_buffereds[i] >= 0) {
+      VOID_TEMP_FAILURE_RETRY(::close(fd_buffereds[i]));
+      fd_buffereds[i] = -1;
+    } else {
+      break;
+    }
+  }
   return r;
 }
 
@@ -201,14 +236,15 @@ void KernelDevice::close()
     vdo_fd = -1;
   }
 
-  ceph_assert(fd_direct >= 0);
-  VOID_TEMP_FAILURE_RETRY(::close(fd_direct));
-  fd_direct = -1;
-
-  ceph_assert(fd_buffered >= 0);
-  VOID_TEMP_FAILURE_RETRY(::close(fd_buffered));
-  fd_buffered = -1;
+  for (int i = 0; i < WRITE_LIFE_MAX; i++) {
+    assert(fd_directs[i] >= 0);
+    VOID_TEMP_FAILURE_RETRY(::close(fd_directs[i]));
+    fd_directs[i] = -1;
 
+    assert(fd_buffereds[i] >= 0);
+    VOID_TEMP_FAILURE_RETRY(::close(fd_buffereds[i]));
+    fd_buffereds[i] = -1;
+  }
   path.clear();
 }
 
@@ -232,14 +268,14 @@ int KernelDevice::collect_metadata(const string& prefix, map<string,string> *pm)
   }
 
   struct stat st;
-  int r = ::fstat(fd_buffered, &st);
+  int r = ::fstat(fd_buffereds[WRITE_LIFE_NOT_SET], &st);
   if (r < 0)
     return -errno;
   if (S_ISBLK(st.st_mode)) {
     (*pm)[prefix + "access_mode"] = "blk";
 
     char buffer[1024] = {0};
-    BlkDev blkdev{fd_buffered};
+    BlkDev blkdev{fd_buffereds[WRITE_LIFE_NOT_SET]};
     if (r = blkdev.partition(buffer, sizeof(buffer)); r) {
       (*pm)[prefix + "partition_path"] = "unknown";
     } else {
@@ -296,6 +332,14 @@ bool KernelDevice::get_thin_utilization(uint64_t *total, uint64_t *avail) const
   return get_vdo_utilization(vdo_fd, total, avail);
 }
 
+int KernelDevice::choose_fd(bool buffered, int write_hint) const
+{
+  assert(write_hint >= WRITE_LIFE_NOT_SET && write_hint < WRITE_LIFE_MAX);
+  if (!enable_wrt)
+    write_hint = WRITE_LIFE_NOT_SET;
+  return buffered ? fd_buffereds[write_hint] : fd_directs[write_hint];
+}
+
 int KernelDevice::flush()
 {
   // protect flush with a mutex.  note that we are not really protecting
@@ -327,7 +371,7 @@ int KernelDevice::flush()
     _exit(1);
   }
   utime_t start = ceph_clock_now();
-  int r = ::fdatasync(fd_direct);
+  int r = ::fdatasync(fd_directs[WRITE_LIFE_NOT_SET]);
   utime_t end = ceph_clock_now();
   utime_t dur = end - start;
   if (r < 0) {
@@ -663,7 +707,7 @@ void KernelDevice::aio_submit(IOContext *ioc)
   }
 }
 
-int KernelDevice::_sync_write(uint64_t off, bufferlist &bl, bool buffered)
+int KernelDevice::_sync_write(uint64_t off, bufferlist &bl, bool buffered, int write_hint)
 {
   uint64_t len = bl.length();
   dout(5) << __func__ << " 0x" << std::hex << off << "~" << len
@@ -677,7 +721,7 @@ int KernelDevice::_sync_write(uint64_t off, bufferlist &bl, bool buffered)
   }
   vector<iovec> iov;
   bl.prepare_iov(&iov);
-  int r = ::pwritev(buffered ? fd_buffered : fd_direct,
+  int r = ::pwritev(choose_fd(buffered, write_hint),
                    &iov[0], iov.size(), off);
 
   if (r < 0) {
@@ -687,7 +731,7 @@ int KernelDevice::_sync_write(uint64_t off, bufferlist &bl, bool buffered)
   }
   if (buffered) {
     // initiate IO (but do not wait)
-    r = ::sync_file_range(fd_buffered, off, len, SYNC_FILE_RANGE_WRITE);
+    r = ::sync_file_range(fd_buffereds[WRITE_LIFE_NOT_SET], off, len, SYNC_FILE_RANGE_WRITE);
     if (r < 0) {
       r = -errno;
       derr << __func__ << " sync_file_range error: " << cpp_strerror(r) << dendl;
@@ -703,7 +747,8 @@ int KernelDevice::_sync_write(uint64_t off, bufferlist &bl, bool buffered)
 int KernelDevice::write(
   uint64_t off,
   bufferlist &bl,
-  bool buffered)
+  bool buffered,
+  int write_hint)
 {
   uint64_t len = bl.length();
   dout(20) << __func__ << " 0x" << std::hex << off << "~" << len << std::dec
@@ -719,14 +764,15 @@ int KernelDevice::write(
   bl.hexdump(*_dout);
   *_dout << dendl;
 
-  return _sync_write(off, bl, buffered);
+  return _sync_write(off, bl, buffered, write_hint);
 }
 
 int KernelDevice::aio_write(
   uint64_t off,
   bufferlist &bl,
   IOContext *ioc,
-  bool buffered)
+  bool buffered,
+  int write_hint)
 {
   uint64_t len = bl.length();
   dout(20) << __func__ << " 0x" << std::hex << off << "~" << len << std::dec
@@ -746,7 +792,7 @@ int KernelDevice::aio_write(
 
 #ifdef HAVE_LIBAIO
   if (aio && dio && !buffered) {
-    ioc->pending_aios.push_back(aio_t(ioc, fd_direct));
+    ioc->pending_aios.push_back(aio_t(ioc, choose_fd(false, write_hint)));
     ++ioc->num_pending;
     aio_t& aio = ioc->pending_aios.back();
     if (cct->_conf->bdev_inject_crash &&
@@ -769,7 +815,7 @@ int KernelDevice::aio_write(
   } else
 #endif
   {
-    int r = _sync_write(off, bl, buffered);
+    int r = _sync_write(off, bl, buffered, write_hint);
     _aio_log_finish(ioc, off, len);
     if (r < 0)
       return r;
@@ -785,7 +831,7 @@ int KernelDevice::discard(uint64_t offset, uint64_t len)
               << " 0x" << std::hex << offset << "~" << len << std::dec
               << dendl;
 
-      r = BlkDev{fd_direct}.discard((int64_t)offset, (int64_t)len);
+      r = BlkDev{fd_directs[WRITE_LIFE_NOT_SET]}.discard((int64_t)offset, (int64_t)len);
   }
   return r;
 }
@@ -802,7 +848,7 @@ int KernelDevice::read(uint64_t off, uint64_t len, bufferlist *pbl,
   _aio_log_start(ioc, off, len);
 
   bufferptr p = buffer::create_small_page_aligned(len);
-  int r = ::pread(buffered ? fd_buffered : fd_direct,
+  int r = ::pread(buffered ? fd_buffereds[WRITE_LIFE_NOT_SET] : fd_directs[WRITE_LIFE_NOT_SET],
                  p.c_str(), len, off);
   if (r < 0) {
     r = -errno;
@@ -834,7 +880,7 @@ int KernelDevice::aio_read(
   if (aio && dio) {
     ceph_assert(is_valid_io(off, len));
     _aio_log_start(ioc, off, len);
-    ioc->pending_aios.push_back(aio_t(ioc, fd_direct));
+    ioc->pending_aios.push_back(aio_t(ioc, fd_directs[WRITE_LIFE_NOT_SET]));
     ++ioc->num_pending;
     aio_t& aio = ioc->pending_aios.back();
     aio.pread(off, len);
@@ -858,7 +904,7 @@ int KernelDevice::direct_read_unaligned(uint64_t off, uint64_t len, char *buf)
   bufferptr p = buffer::create_small_page_aligned(aligned_len);
   int r = 0;
 
-  r = ::pread(fd_direct, p.c_str(), aligned_len, aligned_off);
+  r = ::pread(fd_directs[WRITE_LIFE_NOT_SET], p.c_str(), aligned_len, aligned_off);
   if (r < 0) {
     r = -errno;
     derr << __func__ << " 0x" << std::hex << off << "~" << len << std::dec
@@ -899,7 +945,7 @@ int KernelDevice::read_random(uint64_t off, uint64_t len, char *buf,
     char *t = buf;
     uint64_t left = len;
     while (left > 0) {
-      r = ::pread(fd_buffered, t, left, off);
+      r = ::pread(fd_buffereds[WRITE_LIFE_NOT_SET], t, left, off);
       if (r < 0) {
        r = -errno;
         derr << __func__ << " 0x" << std::hex << off << "~" << left
@@ -912,7 +958,7 @@ int KernelDevice::read_random(uint64_t off, uint64_t len, char *buf,
     }
   } else {
     //direct and aligned read
-    r = ::pread(fd_direct, buf, len, off);
+    r = ::pread(fd_directs[WRITE_LIFE_NOT_SET], buf, len, off);
     if (r < 0) {
       r = -errno;
       derr << __func__ << " direct_aligned_read" << " 0x" << std::hex
@@ -939,7 +985,7 @@ int KernelDevice::invalidate_cache(uint64_t off, uint64_t len)
          << dendl;
   ceph_assert(off % block_size == 0);
   ceph_assert(len % block_size == 0);
-  int r = posix_fadvise(fd_buffered, off, len, POSIX_FADV_DONTNEED);
+  int r = posix_fadvise(fd_buffereds[WRITE_LIFE_NOT_SET], off, len, POSIX_FADV_DONTNEED);
   if (r) {
     r = -r;
     derr << __func__ << " 0x" << std::hex << off << "~" << len << std::dec
index 229d5a8ad5ad929daff5cc1d80684cbf0ef5dd01..e4dbcda37048a2c417a99d25acc2002d5d36811c 100644 (file)
@@ -26,7 +26,8 @@
 #include "BlockDevice.h"
 
 class KernelDevice : public BlockDevice {
-  int fd_direct, fd_buffered;
+  std::vector<int> fd_directs, fd_buffereds;
+  bool enable_wrt = true;
   std::string path;
   bool aio, dio;
 
@@ -87,7 +88,7 @@ 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 _sync_write(uint64_t off, bufferlist& bl, bool buffered, int write_hint);
 
   int _lock();
 
@@ -102,6 +103,7 @@ class KernelDevice : public BlockDevice {
   void debug_aio_unlink(aio_t& aio);
 
   void _detect_vdo();
+  int choose_fd(bool buffered, int write_hint) const;
 
 public:
   KernelDevice(CephContext* cct, aio_callback_t cb, void *cbpriv, aio_callback_t d_cb, void *d_cbpriv);
@@ -128,10 +130,11 @@ 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 write(uint64_t off, bufferlist& bl, bool buffered, int write_hint = WRITE_LIFE_NOT_SET) override;
   int aio_write(uint64_t off, bufferlist& bl,
                IOContext *ioc,
-               bool buffered) override;
+               bool buffered,
+               int write_hint = WRITE_LIFE_NOT_SET) override;
   int flush() override;
   int discard(uint64_t offset, uint64_t len) override;
 
index 104e94046212be880eba8f93fddd116d80ade08c..0797f5bc2fbd95e014359603a119cc49ab9f3f6a 100644 (file)
@@ -819,7 +819,8 @@ int NVMEDevice::aio_write(
     uint64_t off,
     bufferlist &bl,
     IOContext *ioc,
-    bool buffered)
+    bool buffered,
+    int write_hint)
 {
   uint64_t len = bl.length();
   dout(20) << __func__ << " " << off << "~" << len << " ioc " << ioc
@@ -832,7 +833,7 @@ int NVMEDevice::aio_write(
   return 0;
 }
 
-int NVMEDevice::write(uint64_t off, bufferlist &bl, bool buffered)
+int NVMEDevice::write(uint64_t off, bufferlist &bl, bool buffered, int write_hint)
 {
   uint64_t len = bl.length();
   dout(20) << __func__ << " " << off << "~" << len << " buffered "
index b0eba9e57c5b5dc608cb18fa2ed65b2ee24ec5d3..f44aeb59784f2760471efb0997857f9a6107a020 100644 (file)
@@ -67,8 +67,9 @@ class NVMEDevice : public BlockDevice {
     IOContext *ioc) override;
   int aio_write(uint64_t off, bufferlist& bl,
                 IOContext *ioc,
-                bool buffered) override;
-  int write(uint64_t off, bufferlist& bl, bool buffered) override;
+                bool buffered,
+               int write_hint = WRITE_LIFE_NOT_SET) override;
+  int write(uint64_t off, bufferlist& bl, bool buffered, int write_hint = WRITE_LIFE_NOT_SET) override;
   int flush() override;
   int read_random(uint64_t off, uint64_t len, char *buf, bool buffered) override;
 
index 2e7a90566d97afb99166a739f65c99653c5ad6b2..1f9d9599b1e1af93c416951cb328323726ebf9ac 100644 (file)
@@ -184,7 +184,7 @@ void PMEMDevice::aio_submit(IOContext *ioc)
   return;
 }
 
-int PMEMDevice::write(uint64_t off, bufferlist& bl, bool buffered)
+int PMEMDevice::write(uint64_t off, bufferlist& bl, bool buffered, int write_hint = WRITE_LIFE_NOT_SET)
 {
   uint64_t len = bl.length();
   dout(20) << __func__ << " " << off << "~" << len  << dendl;
@@ -218,7 +218,8 @@ int PMEMDevice::aio_write(
   uint64_t off,
   bufferlist &bl,
   IOContext *ioc,
-  bool buffered)
+  bool buffered,
+  int write_hint = WRITE_LIFE_NOT_SET)
 {
   return write(off, bl, buffered);
 }
index 1d681668ae00c187e0c4a2de514456df142256e6..51c602968db1c271555da0e10670c91551cf715d 100644 (file)
@@ -50,10 +50,11 @@ 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 write(uint64_t off, bufferlist& bl, bool buffered, int write_hint = WRITE_LIFE_NOT_SET) override;
   int aio_write(uint64_t off, bufferlist& bl,
                IOContext *ioc,
-               bool buffered) override;
+               bool buffered,
+               int write_hint = WRITE_LIFE_NOT_SET) override;
   int flush() override;
 
   // for managing buffered readers/writers