]>
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" | |
9 | #include "common/WorkQueue.h" | |
224ce89b | 10 | #include "librbd/io/Types.h" |
7c673cae FG |
11 | |
12 | #include <list> | |
13 | #include <atomic> | |
14 | ||
15 | namespace librbd { | |
16 | ||
17 | class ImageCtx; | |
18 | ||
19 | namespace io { | |
20 | ||
21 | class AioCompletion; | |
22 | template <typename> class ImageRequest; | |
23 | class ReadResult; | |
24 | ||
224ce89b WB |
25 | template <typename ImageCtxT = librbd::ImageCtx> |
26 | class ImageRequestWQ | |
27 | : public ThreadPool::PointerWQ<ImageRequest<ImageCtxT> > { | |
7c673cae | 28 | public: |
224ce89b | 29 | ImageRequestWQ(ImageCtxT *image_ctx, const string &name, time_t ti, |
7c673cae FG |
30 | ThreadPool *tp); |
31 | ||
32 | ssize_t read(uint64_t off, uint64_t len, ReadResult &&read_result, | |
33 | int op_flags); | |
34 | ssize_t write(uint64_t off, uint64_t len, bufferlist &&bl, int op_flags); | |
35 | ssize_t discard(uint64_t off, uint64_t len, bool skip_partial_discard); | |
36 | ssize_t writesame(uint64_t off, uint64_t len, bufferlist &&bl, int op_flags); | |
37 | ||
38 | void aio_read(AioCompletion *c, uint64_t off, uint64_t len, | |
39 | ReadResult &&read_result, int op_flags, bool native_async=true); | |
40 | void aio_write(AioCompletion *c, uint64_t off, uint64_t len, | |
41 | bufferlist &&bl, int op_flags, bool native_async=true); | |
42 | void aio_discard(AioCompletion *c, uint64_t off, uint64_t len, | |
43 | bool skip_partial_discard, bool native_async=true); | |
44 | void aio_flush(AioCompletion *c, bool native_async=true); | |
45 | void aio_writesame(AioCompletion *c, uint64_t off, uint64_t len, | |
46 | bufferlist &&bl, int op_flags, bool native_async=true); | |
47 | ||
224ce89b | 48 | using ThreadPool::PointerWQ<ImageRequest<ImageCtxT> >::drain; |
7c673cae | 49 | |
224ce89b | 50 | using ThreadPool::PointerWQ<ImageRequest<ImageCtxT> >::empty; |
7c673cae FG |
51 | |
52 | void shut_down(Context *on_shutdown); | |
53 | ||
7c673cae FG |
54 | inline bool writes_blocked() const { |
55 | RWLock::RLocker locker(m_lock); | |
56 | return (m_write_blockers > 0); | |
57 | } | |
58 | ||
59 | int block_writes(); | |
60 | void block_writes(Context *on_blocked); | |
61 | void unblock_writes(); | |
62 | ||
224ce89b | 63 | void set_require_lock(Direction direction, bool enabled); |
7c673cae FG |
64 | |
65 | protected: | |
66 | void *_void_dequeue() override; | |
224ce89b | 67 | void process(ImageRequest<ImageCtxT> *req) override; |
7c673cae FG |
68 | |
69 | private: | |
70 | typedef std::list<Context *> Contexts; | |
71 | ||
224ce89b WB |
72 | struct C_AcquireLock; |
73 | struct C_BlockedWrites; | |
74 | struct C_RefreshFinish; | |
75 | ||
76 | ImageCtxT &m_image_ctx; | |
7c673cae FG |
77 | mutable RWLock m_lock; |
78 | Contexts m_write_blocker_contexts; | |
224ce89b | 79 | uint32_t m_write_blockers = 0; |
7c673cae | 80 | bool m_require_lock_on_read = false; |
224ce89b | 81 | bool m_require_lock_on_write = false; |
7c673cae FG |
82 | std::atomic<unsigned> m_queued_reads { 0 }; |
83 | std::atomic<unsigned> m_queued_writes { 0 }; | |
224ce89b WB |
84 | std::atomic<unsigned> m_in_flight_ios { 0 }; |
85 | std::atomic<unsigned> m_in_flight_writes { 0 }; | |
86 | std::atomic<unsigned> m_io_blockers { 0 }; | |
7c673cae | 87 | |
224ce89b WB |
88 | bool m_shutdown = false; |
89 | Context *m_on_shutdown = nullptr; | |
7c673cae | 90 | |
224ce89b | 91 | bool is_lock_required(bool write_op) const; |
7c673cae | 92 | |
224ce89b WB |
93 | inline bool require_lock_on_read() const { |
94 | RWLock::RLocker locker(m_lock); | |
95 | return m_require_lock_on_read; | |
96 | } | |
7c673cae FG |
97 | inline bool writes_empty() const { |
98 | RWLock::RLocker locker(m_lock); | |
99 | return (m_queued_writes == 0); | |
100 | } | |
101 | ||
224ce89b WB |
102 | void finish_queued_io(ImageRequest<ImageCtxT> *req); |
103 | void finish_in_flight_write(); | |
7c673cae | 104 | |
224ce89b WB |
105 | int start_in_flight_io(AioCompletion *c); |
106 | void finish_in_flight_io(); | |
107 | void fail_in_flight_io(int r, ImageRequest<ImageCtxT> *req); | |
7c673cae | 108 | |
224ce89b | 109 | void queue(ImageRequest<ImageCtxT> *req); |
7c673cae | 110 | |
224ce89b WB |
111 | void handle_acquire_lock(int r, ImageRequest<ImageCtxT> *req); |
112 | void handle_refreshed(int r, ImageRequest<ImageCtxT> *req); | |
7c673cae FG |
113 | void handle_blocked_writes(int r); |
114 | }; | |
115 | ||
116 | } // namespace io | |
117 | } // namespace librbd | |
118 | ||
224ce89b WB |
119 | extern template class librbd::io::ImageRequestWQ<librbd::ImageCtx>; |
120 | ||
7c673cae | 121 | #endif // CEPH_LIBRBD_IO_IMAGE_REQUEST_WQ_H |