]> git.proxmox.com Git - ceph.git/blame - ceph/src/librbd/io/ImageRequestWQ.h
import 15.2.0 Octopus source
[ceph.git] / ceph / src / librbd / io / ImageRequestWQ.h
CommitLineData
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#ifndef CEPH_LIBRBD_IO_IMAGE_REQUEST_WQ_H
5#define CEPH_LIBRBD_IO_IMAGE_REQUEST_WQ_H
6
7#include "include/Context.h"
9f95a23c 8#include "common/ceph_mutex.h"
11fdf7f2 9#include "common/Throttle.h"
7c673cae 10#include "common/WorkQueue.h"
224ce89b 11#include "librbd/io/Types.h"
9f95a23c 12#include "include/interval_set.h"
7c673cae
FG
13#include <list>
14#include <atomic>
9f95a23c 15#include <vector>
7c673cae
FG
16
17namespace librbd {
18
19class ImageCtx;
20
21namespace io {
22
23class AioCompletion;
11fdf7f2 24template <typename> class ImageDispatchSpec;
7c673cae
FG
25class ReadResult;
26
224ce89b
WB
27template <typename ImageCtxT = librbd::ImageCtx>
28class ImageRequestWQ
11fdf7f2 29 : public ThreadPool::PointerWQ<ImageDispatchSpec<ImageCtxT> > {
7c673cae 30public:
224ce89b 31 ImageRequestWQ(ImageCtxT *image_ctx, const string &name, time_t ti,
7c673cae 32 ThreadPool *tp);
11fdf7f2 33 ~ImageRequestWQ();
7c673cae
FG
34
35 ssize_t read(uint64_t off, uint64_t len, ReadResult &&read_result,
36 int op_flags);
37 ssize_t write(uint64_t off, uint64_t len, bufferlist &&bl, int op_flags);
11fdf7f2
TL
38 ssize_t discard(uint64_t off, uint64_t len,
39 uint32_t discard_granularity_bytes);
7c673cae 40 ssize_t writesame(uint64_t off, uint64_t len, bufferlist &&bl, int op_flags);
c07f9fc5
FG
41 ssize_t compare_and_write(uint64_t off, uint64_t len,
42 bufferlist &&cmp_bl, bufferlist &&bl,
43 uint64_t *mismatch_off, int op_flags);
11fdf7f2 44 int flush();
7c673cae
FG
45
46 void aio_read(AioCompletion *c, uint64_t off, uint64_t len,
47 ReadResult &&read_result, int op_flags, bool native_async=true);
48 void aio_write(AioCompletion *c, uint64_t off, uint64_t len,
49 bufferlist &&bl, int op_flags, bool native_async=true);
50 void aio_discard(AioCompletion *c, uint64_t off, uint64_t len,
11fdf7f2 51 uint32_t discard_granularity_bytes, bool native_async=true);
7c673cae
FG
52 void aio_flush(AioCompletion *c, bool native_async=true);
53 void aio_writesame(AioCompletion *c, uint64_t off, uint64_t len,
54 bufferlist &&bl, int op_flags, bool native_async=true);
c07f9fc5
FG
55 void aio_compare_and_write(AioCompletion *c, uint64_t off,
56 uint64_t len, bufferlist &&cmp_bl,
57 bufferlist &&bl, uint64_t *mismatch_off,
58 int op_flags, bool native_async=true);
7c673cae 59
11fdf7f2
TL
60 using ThreadPool::PointerWQ<ImageDispatchSpec<ImageCtxT> >::drain;
61 using ThreadPool::PointerWQ<ImageDispatchSpec<ImageCtxT> >::empty;
7c673cae
FG
62
63 void shut_down(Context *on_shutdown);
64
7c673cae 65 inline bool writes_blocked() const {
9f95a23c 66 std::shared_lock locker{m_lock};
7c673cae
FG
67 return (m_write_blockers > 0);
68 }
69
70 int block_writes();
71 void block_writes(Context *on_blocked);
72 void unblock_writes();
73
11fdf7f2
TL
74 void wait_on_writes_unblocked(Context *on_unblocked);
75
224ce89b 76 void set_require_lock(Direction direction, bool enabled);
7c673cae 77
11fdf7f2
TL
78 void apply_qos_schedule_tick_min(uint64_t tick);
79
80 void apply_qos_limit(const uint64_t flag, uint64_t limit, uint64_t burst);
9f95a23c 81
7c673cae
FG
82protected:
83 void *_void_dequeue() override;
11fdf7f2
TL
84 void process(ImageDispatchSpec<ImageCtxT> *req) override;
85 bool _empty() override {
86 return (ThreadPool::PointerWQ<ImageDispatchSpec<ImageCtxT>>::_empty() &&
87 m_io_throttled.load() == 0);
88 }
89
7c673cae
FG
90
91private:
92 typedef std::list<Context *> Contexts;
93
224ce89b
WB
94 struct C_AcquireLock;
95 struct C_BlockedWrites;
96 struct C_RefreshFinish;
97
98 ImageCtxT &m_image_ctx;
9f95a23c 99 mutable ceph::shared_mutex m_lock;
7c673cae 100 Contexts m_write_blocker_contexts;
224ce89b 101 uint32_t m_write_blockers = 0;
11fdf7f2 102 Contexts m_unblocked_write_waiter_contexts;
7c673cae 103 bool m_require_lock_on_read = false;
224ce89b 104 bool m_require_lock_on_write = false;
7c673cae
FG
105 std::atomic<unsigned> m_queued_reads { 0 };
106 std::atomic<unsigned> m_queued_writes { 0 };
224ce89b
WB
107 std::atomic<unsigned> m_in_flight_ios { 0 };
108 std::atomic<unsigned> m_in_flight_writes { 0 };
109 std::atomic<unsigned> m_io_blockers { 0 };
11fdf7f2
TL
110 std::atomic<unsigned> m_io_throttled { 0 };
111
9f95a23c
TL
112 typedef interval_set<uint64_t> ImageExtentIntervals;
113 ImageExtentIntervals m_in_flight_extents;
114
115 std::vector<ImageDispatchSpec<ImageCtxT>*> m_blocked_ios;
116 std::atomic<unsigned> m_last_tid { 0 };
117 std::set<uint64_t> m_queued_or_blocked_io_tids;
118 std::map<uint64_t, ImageDispatchSpec<ImageCtxT>*> m_queued_flushes;
119
11fdf7f2
TL
120 std::list<std::pair<uint64_t, TokenBucketThrottle*> > m_throttles;
121 uint64_t m_qos_enabled_flag = 0;
7c673cae 122
224ce89b
WB
123 bool m_shutdown = false;
124 Context *m_on_shutdown = nullptr;
7c673cae 125
224ce89b 126 bool is_lock_required(bool write_op) const;
7c673cae 127
224ce89b 128 inline bool require_lock_on_read() const {
9f95a23c 129 std::shared_lock locker{m_lock};
224ce89b
WB
130 return m_require_lock_on_read;
131 }
7c673cae 132 inline bool writes_empty() const {
9f95a23c 133 std::shared_lock locker{m_lock};
7c673cae
FG
134 return (m_queued_writes == 0);
135 }
136
11fdf7f2
TL
137 bool needs_throttle(ImageDispatchSpec<ImageCtxT> *item);
138
9f95a23c
TL
139 void finish_queued_io(bool write_op);
140 void remove_in_flight_write_ios(uint64_t offset, uint64_t length,
141 bool write_op, uint64_t tid);
224ce89b 142 void finish_in_flight_write();
7c673cae 143
9f95a23c
TL
144 void unblock_flushes();
145 bool block_overlapping_io(ImageExtentIntervals* in_flight_image_extents,
146 uint64_t object_off, uint64_t object_len);
147 void unblock_overlapping_io(uint64_t offset, uint64_t length, uint64_t tid);
224ce89b
WB
148 int start_in_flight_io(AioCompletion *c);
149 void finish_in_flight_io();
11fdf7f2 150 void fail_in_flight_io(int r, ImageDispatchSpec<ImageCtxT> *req);
9f95a23c 151 void process_io(ImageDispatchSpec<ImageCtxT> *req, bool non_blocking_io);
7c673cae 152
11fdf7f2 153 void queue(ImageDispatchSpec<ImageCtxT> *req);
9f95a23c
TL
154 void queue_unblocked_io(AioCompletion *comp,
155 ImageDispatchSpec<ImageCtxT> *req);
7c673cae 156
11fdf7f2
TL
157 void handle_acquire_lock(int r, ImageDispatchSpec<ImageCtxT> *req);
158 void handle_refreshed(int r, ImageDispatchSpec<ImageCtxT> *req);
7c673cae 159 void handle_blocked_writes(int r);
11fdf7f2
TL
160
161 void handle_throttle_ready(int r, ImageDispatchSpec<ImageCtxT> *item, uint64_t flag);
7c673cae
FG
162};
163
164} // namespace io
165} // namespace librbd
166
224ce89b
WB
167extern template class librbd::io::ImageRequestWQ<librbd::ImageCtx>;
168
7c673cae 169#endif // CEPH_LIBRBD_IO_IMAGE_REQUEST_WQ_H