]>
git.proxmox.com Git - ceph.git/blob - ceph/src/os/bluestore/BlockDevice.cc
832f6b85393f84569feb60b7fe8e98b85b3fc7ee
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 "BlockDevice.h"
22 #if defined(HAVE_LIBAIO) || defined(HAVE_POSIXAIO)
23 #include "KernelDevice.h"
26 #if defined(HAVE_SPDK)
27 #include "NVMEDevice.h"
30 #if defined(HAVE_BLUESTORE_PMEM)
31 #include "PMEMDevice.h"
35 #include "common/debug.h"
36 #include "common/EventTrace.h"
37 #include "common/errno.h"
38 #include "include/compat.h"
40 #define dout_context cct
41 #define dout_subsys ceph_subsys_bdev
43 #define dout_prefix *_dout << "bdev "
45 void IOContext::aio_wait()
47 std::unique_lock
l(lock
);
48 // see _aio_thread for waker logic
49 while (num_running
.load() > 0) {
50 dout(10) << __func__
<< " " << this
51 << " waiting for " << num_running
.load() << " aios to complete"
55 dout(20) << __func__
<< " " << this << " done" << dendl
;
58 uint64_t IOContext::get_num_ios() const
60 // this is about the simplest model for transaction cost you can
61 // imagine. there is some fixed overhead cost by saying there is a
62 // minimum of one "io". and then we have some cost per "io" that is
63 // a configurable (with different hdd and ssd defaults), and add
64 // that to the bytes value.
66 #if defined(HAVE_LIBAIO) || defined(HAVE_POSIXAIO)
67 for (auto& p
: pending_aios
) {
77 void IOContext::release_running_aios()
79 ceph_assert(!num_running
);
80 #if defined(HAVE_LIBAIO) || defined(HAVE_POSIXAIO)
81 // release aio contexts (including pinned buffers).
86 BlockDevice
*BlockDevice::create(CephContext
* cct
, const string
& path
,
87 aio_callback_t cb
, void *cbpriv
, aio_callback_t d_cb
, void *d_cbpriv
)
89 string type
= "kernel";
90 char buf
[PATH_MAX
+ 1];
91 int r
= ::readlink(path
.c_str(), buf
, sizeof(buf
) - 1);
94 char *bname
= ::basename(buf
);
95 if (strncmp(bname
, SPDK_PREFIX
, sizeof(SPDK_PREFIX
)-1) == 0)
99 #if defined(HAVE_BLUESTORE_PMEM)
100 if (type
== "kernel") {
103 void *addr
= pmem_map_file(path
.c_str(), 0, PMEM_FILE_EXCL
, O_RDONLY
, &map_len
, &is_pmem
);
108 dout(1) << path
.c_str() << " isn't pmem file" << dendl
;
109 pmem_unmap(addr
, map_len
);
111 dout(1) << "pmem_map_file:" << path
.c_str() << " failed." << pmem_errormsg() << dendl
;
116 dout(1) << __func__
<< " path " << path
<< " type " << type
<< dendl
;
118 #if defined(HAVE_BLUESTORE_PMEM)
119 if (type
== "pmem") {
120 return new PMEMDevice(cct
, cb
, cbpriv
);
123 #if defined(HAVE_LIBAIO) || defined(HAVE_POSIXAIO)
124 if (type
== "kernel") {
125 return new KernelDevice(cct
, cb
, cbpriv
, d_cb
, d_cbpriv
);
129 #if defined(HAVE_SPDK)
130 if (type
== "ust-nvme") {
131 return new NVMEDevice(cct
, cb
, cbpriv
);
136 derr
<< __func__
<< " unknown backend " << type
<< dendl
;
141 void BlockDevice::queue_reap_ioc(IOContext
*ioc
)
143 std::lock_guard
l(ioc_reap_lock
);
144 if (ioc_reap_count
.load() == 0)
146 ioc_reap_queue
.push_back(ioc
);
149 void BlockDevice::reap_ioc()
151 if (ioc_reap_count
.load()) {
152 std::lock_guard
l(ioc_reap_lock
);
153 for (auto p
: ioc_reap_queue
) {
154 dout(20) << __func__
<< " reap ioc " << p
<< dendl
;
157 ioc_reap_queue
.clear();