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