]> git.proxmox.com Git - ceph.git/blob - ceph/src/blk/zoned/HMSMRDevice.h
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / blk / zoned / HMSMRDevice.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2014 Red Hat
7 * Copyright (C) 2020 Abutalib Aghayev
8 *
9 * This is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License version 2.1, as published by the Free Software
12 * Foundation. See file COPYING.
13 *
14 */
15
16 // Copied from KernelDevice with HM-SMR specific functionality added. Will be
17 // further specialized for HM-SMR.
18
19 #ifndef CEPH_BLK_HMSMRDEVICE_H
20 #define CEPH_BLK_HMSMRDEVICE_H
21
22 #include <atomic>
23
24 #include "include/types.h"
25 #include "include/interval_set.h"
26 #include "common/Thread.h"
27 #include "include/utime.h"
28
29 #include "aio/aio.h"
30 #include "BlockDevice.h"
31
32 #define RW_IO_MAX (INT_MAX & CEPH_PAGE_MASK)
33
34 class HMSMRDevice final : public BlockDevice {
35 std::vector<int> fd_directs, fd_buffereds;
36 bool enable_wrt = true;
37 std::string path;
38 bool aio, dio;
39
40 int vdo_fd = -1; ///< fd for vdo sysfs directory
41 string vdo_name;
42
43 std::string devname; ///< kernel dev name (/sys/block/$devname), if any
44
45 ceph::mutex debug_lock = ceph::make_mutex("HMSMRDevice::debug_lock");
46 interval_set<uint64_t> debug_inflight;
47
48 std::atomic<bool> io_since_flush = {false};
49 ceph::mutex flush_mutex = ceph::make_mutex("HMSMRDevice::flush_mutex");
50
51 std::unique_ptr<io_queue_t> io_queue;
52 aio_callback_t discard_callback;
53 void *discard_callback_priv;
54 bool aio_stop;
55 bool discard_started;
56 bool discard_stop;
57
58 ceph::mutex discard_lock = ceph::make_mutex("HMSMRDevice::discard_lock");
59 ceph::condition_variable discard_cond;
60 bool discard_running = false;
61 interval_set<uint64_t> discard_queued;
62 interval_set<uint64_t> discard_finishing;
63
64 struct AioCompletionThread : public Thread {
65 HMSMRDevice *bdev;
66 explicit AioCompletionThread(HMSMRDevice *b) : bdev(b) {}
67 void *entry() override {
68 bdev->_aio_thread();
69 return NULL;
70 }
71 } aio_thread;
72
73 struct DiscardThread : public Thread {
74 HMSMRDevice *bdev;
75 explicit DiscardThread(HMSMRDevice *b) : bdev(b) {}
76 void *entry() override {
77 bdev->_discard_thread();
78 return NULL;
79 }
80 } discard_thread;
81
82 std::atomic_int injecting_crash;
83
84 void _aio_thread();
85 void _discard_thread();
86 int queue_discard(interval_set<uint64_t> &to_release) final;
87
88 int _aio_start();
89 void _aio_stop();
90
91 int _discard_start();
92 void _discard_stop();
93
94 void _aio_log_start(IOContext *ioc, uint64_t offset, uint64_t length);
95 void _aio_log_finish(IOContext *ioc, uint64_t offset, uint64_t length);
96
97 int _sync_write(uint64_t off, bufferlist& bl, bool buffered, int write_hint);
98
99 int _lock();
100
101 int direct_read_unaligned(uint64_t off, uint64_t len, char *buf);
102
103 // stalled aio debugging
104 aio_list_t debug_queue;
105 ceph::mutex debug_queue_lock =
106 ceph::make_mutex("HMSMRDevice::debug_queue_lock");
107 aio_t *debug_oldest = nullptr;
108 utime_t debug_stall_since;
109 void debug_aio_link(aio_t& aio);
110 void debug_aio_unlink(aio_t& aio);
111
112 void _detect_vdo();
113 int choose_fd(bool buffered, int write_hint) const;
114
115 bool set_smr_params(const std::string& path);
116
117 public:
118 HMSMRDevice(CephContext* cct, aio_callback_t cb, void *cbpriv,
119 aio_callback_t d_cb, void *d_cbpriv);
120 static bool support(const std::string& path);
121
122 void aio_submit(IOContext *ioc) final;
123 void discard_drain() final;
124
125 int collect_metadata(const std::string& prefix,
126 map<std::string,std::string> *pm) const final;
127 int get_devname(std::string *s) const final {
128 if (devname.empty()) {
129 return -ENOENT;
130 }
131 *s = devname;
132 return 0;
133 }
134 int get_devices(std::set<std::string> *ls) const final;
135
136 bool is_smr() const final { return true; }
137
138 bool get_thin_utilization(uint64_t *total, uint64_t *avail) const final;
139
140 int read(uint64_t off, uint64_t len, bufferlist *pbl,
141 IOContext *ioc,
142 bool buffered) final;
143 int aio_read(uint64_t off, uint64_t len, bufferlist *pbl,
144 IOContext *ioc) final;
145 int read_random(uint64_t off, uint64_t len, char *buf,
146 bool buffered) final;
147
148 int write(uint64_t off, bufferlist& bl, bool buffered,
149 int write_hint = WRITE_LIFE_NOT_SET) final;
150 int aio_write(uint64_t off, bufferlist& bl,
151 IOContext *ioc,
152 bool buffered,
153 int write_hint = WRITE_LIFE_NOT_SET) final;
154 int flush() final;
155 int discard(uint64_t offset, uint64_t len) final;
156
157 // for managing buffered readers/writers
158 int invalidate_cache(uint64_t off, uint64_t len) final;
159 int open(const std::string& path) final;
160 void close() final;
161 };
162
163 #endif //CEPH_BLK_HMSMRDEVICE_H