1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2015 XSky <haomai@xsky.com>
8 * Author: Haomai Wang <haomaiwang@gmail.com>
10 * This is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License version 2.1, as published by the Free Software
13 * Foundation. See file COPYING.
20 #include "KernelDevice.h"
21 #if defined(HAVE_SPDK)
22 #include "NVMEDevice.h"
25 #if defined(HAVE_PMEM)
26 #include "PMEMDevice.h"
30 #include "common/debug.h"
31 #include "common/EventTrace.h"
32 #include "common/errno.h"
33 #include "include/compat.h"
35 #define dout_context cct
36 #define dout_subsys ceph_subsys_bdev
38 #define dout_prefix *_dout << "bdev "
40 void IOContext::aio_wait()
42 std::unique_lock<std::mutex> l(lock);
43 // see _aio_thread for waker logic
44 while (num_running.load() > 0) {
45 dout(10) << __func__ << " " << this
46 << " waiting for " << num_running.load() << " aios to complete"
50 dout(20) << __func__ << " " << this << " done" << dendl;
53 BlockDevice *BlockDevice::create(CephContext* cct, const string& path,
54 aio_callback_t cb, void *cbpriv)
56 string type = "kernel";
57 char buf[PATH_MAX + 1];
58 int r = ::readlink(path.c_str(), buf, sizeof(buf) - 1);
61 char *bname = ::basename(buf);
62 if (strncmp(bname, SPDK_PREFIX, sizeof(SPDK_PREFIX)-1) == 0)
66 #if defined(HAVE_PMEM)
67 if (type == "kernel") {
69 void *addr = pmem_map_file(path.c_str(), 1024*1024, PMEM_FILE_EXCL, O_RDONLY, NULL, &is_pmem);
73 pmem_unmap(addr, 1024*1024);
78 dout(1) << __func__ << " path " << path << " type " << type << dendl;
80 #if defined(HAVE_PMEM)
82 return new PMEMDevice(cct, cb, cbpriv);
86 if (type == "kernel") {
87 return new KernelDevice(cct, cb, cbpriv);
89 #if defined(HAVE_SPDK)
90 if (type == "ust-nvme") {
91 return new NVMEDevice(cct, cb, cbpriv);
96 derr << __func__ << " unknown backend " << type << dendl;
101 void BlockDevice::queue_reap_ioc(IOContext *ioc)
103 std::lock_guard<std::mutex> l(ioc_reap_lock);
104 if (ioc_reap_count.load() == 0)
106 ioc_reap_queue.push_back(ioc);
109 void BlockDevice::reap_ioc()
111 if (ioc_reap_count.load()) {
112 std::lock_guard<std::mutex> l(ioc_reap_lock);
113 for (auto p : ioc_reap_queue) {
114 dout(20) << __func__ << " reap ioc " << p << dendl;
117 ioc_reap_queue.clear();