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