]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | * | |
8 | * This is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU Lesser General Public | |
10 | * License version 2.1, as published by the Free Software | |
11 | * Foundation. See file COPYING. | |
12 | * | |
13 | */ | |
14 | ||
15 | #ifndef CEPH_OS_BLUESTORE_KERNELDEVICE_H | |
16 | #define CEPH_OS_BLUESTORE_KERNELDEVICE_H | |
17 | ||
18 | #include <atomic> | |
19 | ||
11fdf7f2 | 20 | #include "include/types.h" |
7c673cae | 21 | #include "include/interval_set.h" |
11fdf7f2 TL |
22 | #include "common/Thread.h" |
23 | #include "include/utime.h" | |
7c673cae | 24 | |
11fdf7f2 | 25 | #include "ceph_aio.h" |
7c673cae FG |
26 | #include "BlockDevice.h" |
27 | ||
eafe8130 | 28 | #define RW_IO_MAX (INT_MAX & CEPH_PAGE_MASK) |
494da23a TL |
29 | |
30 | ||
7c673cae | 31 | class KernelDevice : public BlockDevice { |
11fdf7f2 TL |
32 | std::vector<int> fd_directs, fd_buffereds; |
33 | bool enable_wrt = true; | |
7c673cae | 34 | std::string path; |
7c673cae FG |
35 | bool aio, dio; |
36 | ||
11fdf7f2 TL |
37 | int vdo_fd = -1; ///< fd for vdo sysfs directory |
38 | string vdo_name; | |
39 | ||
40 | std::string devname; ///< kernel dev name (/sys/block/$devname), if any | |
41 | ||
42 | ceph::mutex debug_lock = ceph::make_mutex("KernelDevice::debug_lock"); | |
7c673cae FG |
43 | interval_set<uint64_t> debug_inflight; |
44 | ||
45 | std::atomic<bool> io_since_flush = {false}; | |
11fdf7f2 | 46 | ceph::mutex flush_mutex = ceph::make_mutex("KernelDevice::flush_mutex"); |
7c673cae | 47 | |
9f95a23c | 48 | std::unique_ptr<io_queue_t> io_queue; |
11fdf7f2 TL |
49 | aio_callback_t discard_callback; |
50 | void *discard_callback_priv; | |
7c673cae | 51 | bool aio_stop; |
11fdf7f2 TL |
52 | bool discard_started; |
53 | bool discard_stop; | |
54 | ||
55 | ceph::mutex discard_lock = ceph::make_mutex("KernelDevice::discard_lock"); | |
56 | ceph::condition_variable discard_cond; | |
57 | bool discard_running = false; | |
58 | interval_set<uint64_t> discard_queued; | |
59 | interval_set<uint64_t> discard_finishing; | |
7c673cae FG |
60 | |
61 | struct AioCompletionThread : public Thread { | |
62 | KernelDevice *bdev; | |
63 | explicit AioCompletionThread(KernelDevice *b) : bdev(b) {} | |
64 | void *entry() override { | |
65 | bdev->_aio_thread(); | |
66 | return NULL; | |
67 | } | |
68 | } aio_thread; | |
69 | ||
11fdf7f2 TL |
70 | struct DiscardThread : public Thread { |
71 | KernelDevice *bdev; | |
72 | explicit DiscardThread(KernelDevice *b) : bdev(b) {} | |
73 | void *entry() override { | |
74 | bdev->_discard_thread(); | |
75 | return NULL; | |
76 | } | |
77 | } discard_thread; | |
78 | ||
7c673cae FG |
79 | std::atomic_int injecting_crash; |
80 | ||
81 | void _aio_thread(); | |
11fdf7f2 TL |
82 | void _discard_thread(); |
83 | int queue_discard(interval_set<uint64_t> &to_release) override; | |
84 | ||
7c673cae FG |
85 | int _aio_start(); |
86 | void _aio_stop(); | |
87 | ||
11fdf7f2 TL |
88 | int _discard_start(); |
89 | void _discard_stop(); | |
90 | ||
7c673cae FG |
91 | void _aio_log_start(IOContext *ioc, uint64_t offset, uint64_t length); |
92 | void _aio_log_finish(IOContext *ioc, uint64_t offset, uint64_t length); | |
93 | ||
11fdf7f2 | 94 | int _sync_write(uint64_t off, bufferlist& bl, bool buffered, int write_hint); |
7c673cae FG |
95 | |
96 | int _lock(); | |
97 | ||
98 | int direct_read_unaligned(uint64_t off, uint64_t len, char *buf); | |
99 | ||
100 | // stalled aio debugging | |
101 | aio_list_t debug_queue; | |
11fdf7f2 | 102 | ceph::mutex debug_queue_lock = ceph::make_mutex("KernelDevice::debug_queue_lock"); |
7c673cae FG |
103 | aio_t *debug_oldest = nullptr; |
104 | utime_t debug_stall_since; | |
105 | void debug_aio_link(aio_t& aio); | |
106 | void debug_aio_unlink(aio_t& aio); | |
107 | ||
11fdf7f2 TL |
108 | void _detect_vdo(); |
109 | int choose_fd(bool buffered, int write_hint) const; | |
110 | ||
7c673cae | 111 | public: |
11fdf7f2 | 112 | KernelDevice(CephContext* cct, aio_callback_t cb, void *cbpriv, aio_callback_t d_cb, void *d_cbpriv); |
7c673cae FG |
113 | |
114 | void aio_submit(IOContext *ioc) override; | |
11fdf7f2 | 115 | void discard_drain() override; |
7c673cae | 116 | |
11fdf7f2 | 117 | int collect_metadata(const std::string& prefix, map<std::string,std::string> *pm) const override; |
9f95a23c | 118 | int get_devname(std::string *s) const override { |
11fdf7f2 TL |
119 | if (devname.empty()) { |
120 | return -ENOENT; | |
121 | } | |
122 | *s = devname; | |
123 | return 0; | |
7c673cae | 124 | } |
9f95a23c | 125 | int get_devices(std::set<std::string> *ls) const override; |
7c673cae | 126 | |
11fdf7f2 | 127 | bool get_thin_utilization(uint64_t *total, uint64_t *avail) const override; |
7c673cae FG |
128 | |
129 | int read(uint64_t off, uint64_t len, bufferlist *pbl, | |
130 | IOContext *ioc, | |
131 | bool buffered) override; | |
132 | int aio_read(uint64_t off, uint64_t len, bufferlist *pbl, | |
133 | IOContext *ioc) override; | |
134 | int read_random(uint64_t off, uint64_t len, char *buf, bool buffered) override; | |
135 | ||
11fdf7f2 | 136 | int write(uint64_t off, bufferlist& bl, bool buffered, int write_hint = WRITE_LIFE_NOT_SET) override; |
7c673cae FG |
137 | int aio_write(uint64_t off, bufferlist& bl, |
138 | IOContext *ioc, | |
11fdf7f2 TL |
139 | bool buffered, |
140 | int write_hint = WRITE_LIFE_NOT_SET) override; | |
7c673cae | 141 | int flush() override; |
11fdf7f2 | 142 | int discard(uint64_t offset, uint64_t len) override; |
7c673cae FG |
143 | |
144 | // for managing buffered readers/writers | |
145 | int invalidate_cache(uint64_t off, uint64_t len) override; | |
146 | int open(const std::string& path) override; | |
147 | void close() override; | |
148 | }; | |
149 | ||
150 | #endif |