1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #ifndef CEPH_LIBRBD_IO_IMAGE_REQUEST_WQ_H
5 #define CEPH_LIBRBD_IO_IMAGE_REQUEST_WQ_H
7 #include "include/Context.h"
8 #include "common/RWLock.h"
9 #include "common/WorkQueue.h"
21 template <typename
> class ImageRequest
;
24 class ImageRequestWQ
: protected ThreadPool::PointerWQ
<ImageRequest
<ImageCtx
> > {
26 ImageRequestWQ(ImageCtx
*image_ctx
, const string
&name
, time_t ti
,
29 ssize_t
read(uint64_t off
, uint64_t len
, ReadResult
&&read_result
,
31 ssize_t
write(uint64_t off
, uint64_t len
, bufferlist
&&bl
, int op_flags
);
32 ssize_t
discard(uint64_t off
, uint64_t len
, bool skip_partial_discard
);
33 ssize_t
writesame(uint64_t off
, uint64_t len
, bufferlist
&&bl
, int op_flags
);
35 void aio_read(AioCompletion
*c
, uint64_t off
, uint64_t len
,
36 ReadResult
&&read_result
, int op_flags
, bool native_async
=true);
37 void aio_write(AioCompletion
*c
, uint64_t off
, uint64_t len
,
38 bufferlist
&&bl
, int op_flags
, bool native_async
=true);
39 void aio_discard(AioCompletion
*c
, uint64_t off
, uint64_t len
,
40 bool skip_partial_discard
, bool native_async
=true);
41 void aio_flush(AioCompletion
*c
, bool native_async
=true);
42 void aio_writesame(AioCompletion
*c
, uint64_t off
, uint64_t len
,
43 bufferlist
&&bl
, int op_flags
, bool native_async
=true);
45 using ThreadPool::PointerWQ
<ImageRequest
<ImageCtx
> >::drain
;
47 using ThreadPool::PointerWQ
<ImageRequest
<ImageCtx
> >::empty
;
49 void shut_down(Context
*on_shutdown
);
51 bool is_lock_required() const;
52 bool is_lock_request_needed() const;
54 inline bool writes_blocked() const {
55 RWLock::RLocker
locker(m_lock
);
56 return (m_write_blockers
> 0);
60 void block_writes(Context
*on_blocked
);
61 void unblock_writes();
63 void set_require_lock_on_read();
64 void clear_require_lock_on_read();
67 void *_void_dequeue() override
;
68 void process(ImageRequest
<ImageCtx
> *req
) override
;
71 typedef std::list
<Context
*> Contexts
;
73 struct C_RefreshFinish
: public Context
{
74 ImageRequestWQ
*aio_work_queue
;
75 ImageRequest
<ImageCtx
> *aio_image_request
;
77 C_RefreshFinish(ImageRequestWQ
*aio_work_queue
,
78 ImageRequest
<ImageCtx
> *aio_image_request
)
79 : aio_work_queue(aio_work_queue
), aio_image_request(aio_image_request
) {
81 void finish(int r
) override
{
82 aio_work_queue
->handle_refreshed(r
, aio_image_request
);
86 struct C_BlockedWrites
: public Context
{
87 ImageRequestWQ
*aio_work_queue
;
88 C_BlockedWrites(ImageRequestWQ
*_aio_work_queue
)
89 : aio_work_queue(_aio_work_queue
) {
92 void finish(int r
) override
{
93 aio_work_queue
->handle_blocked_writes(r
);
97 ImageCtx
&m_image_ctx
;
98 mutable RWLock m_lock
;
99 Contexts m_write_blocker_contexts
;
100 uint32_t m_write_blockers
;
101 bool m_require_lock_on_read
= false;
102 std::atomic
<unsigned> m_in_progress_writes
{ 0 };
103 std::atomic
<unsigned> m_queued_reads
{ 0 };
104 std::atomic
<unsigned> m_queued_writes
{ 0 };
105 std::atomic
<unsigned> m_in_flight_ops
{ 0 };
107 bool m_refresh_in_progress
;
110 Context
*m_on_shutdown
;
112 inline bool writes_empty() const {
113 RWLock::RLocker
locker(m_lock
);
114 return (m_queued_writes
== 0);
117 void finish_queued_op(ImageRequest
<ImageCtx
> *req
);
118 void finish_in_progress_write();
120 int start_in_flight_op(AioCompletion
*c
);
121 void finish_in_flight_op();
123 void queue(ImageRequest
<ImageCtx
> *req
);
125 void handle_refreshed(int r
, ImageRequest
<ImageCtx
> *req
);
126 void handle_blocked_writes(int r
);
130 } // namespace librbd
132 #endif // CEPH_LIBRBD_IO_IMAGE_REQUEST_WQ_H