Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / librbd / io / ImageRequestWQ.h
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"
10 #include "librbd/io/Types.h"
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
25 template <typename ImageCtxT = librbd::ImageCtx>
26 class ImageRequestWQ
27   : public ThreadPool::PointerWQ<ImageRequest<ImageCtxT> > {
28 public:
29   ImageRequestWQ(ImageCtxT *image_ctx, const string &name, time_t ti,
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   ssize_t compare_and_write(uint64_t off, uint64_t len,
38                             bufferlist &&cmp_bl, bufferlist &&bl,
39                             uint64_t *mismatch_off, int op_flags);
40
41   void aio_read(AioCompletion *c, uint64_t off, uint64_t len,
42                 ReadResult &&read_result, int op_flags, bool native_async=true);
43   void aio_write(AioCompletion *c, uint64_t off, uint64_t len,
44                  bufferlist &&bl, int op_flags, bool native_async=true);
45   void aio_discard(AioCompletion *c, uint64_t off, uint64_t len,
46                    bool skip_partial_discard, bool native_async=true);
47   void aio_flush(AioCompletion *c, bool native_async=true);
48   void aio_writesame(AioCompletion *c, uint64_t off, uint64_t len,
49                      bufferlist &&bl, int op_flags, bool native_async=true);
50   void aio_compare_and_write(AioCompletion *c, uint64_t off,
51                              uint64_t len, bufferlist &&cmp_bl,
52                              bufferlist &&bl, uint64_t *mismatch_off,
53                              int op_flags, bool native_async=true);
54
55   using ThreadPool::PointerWQ<ImageRequest<ImageCtxT> >::drain;
56
57   using ThreadPool::PointerWQ<ImageRequest<ImageCtxT> >::empty;
58
59   void shut_down(Context *on_shutdown);
60
61   inline bool writes_blocked() const {
62     RWLock::RLocker locker(m_lock);
63     return (m_write_blockers > 0);
64   }
65
66   int block_writes();
67   void block_writes(Context *on_blocked);
68   void unblock_writes();
69
70   void set_require_lock(Direction direction, bool enabled);
71
72 protected:
73   void *_void_dequeue() override;
74   void process(ImageRequest<ImageCtxT> *req) override;
75
76 private:
77   typedef std::list<Context *> Contexts;
78
79   struct C_AcquireLock;
80   struct C_BlockedWrites;
81   struct C_RefreshFinish;
82
83   ImageCtxT &m_image_ctx;
84   mutable RWLock m_lock;
85   Contexts m_write_blocker_contexts;
86   uint32_t m_write_blockers = 0;
87   bool m_require_lock_on_read = false;
88   bool m_require_lock_on_write = false;
89   std::atomic<unsigned> m_queued_reads { 0 };
90   std::atomic<unsigned> m_queued_writes { 0 };
91   std::atomic<unsigned> m_in_flight_ios { 0 };
92   std::atomic<unsigned> m_in_flight_writes { 0 };
93   std::atomic<unsigned> m_io_blockers { 0 };
94
95   bool m_shutdown = false;
96   Context *m_on_shutdown = nullptr;
97
98   bool is_lock_required(bool write_op) const;
99
100   inline bool require_lock_on_read() const {
101     RWLock::RLocker locker(m_lock);
102     return m_require_lock_on_read;
103   }
104   inline bool writes_empty() const {
105     RWLock::RLocker locker(m_lock);
106     return (m_queued_writes == 0);
107   }
108
109   void finish_queued_io(ImageRequest<ImageCtxT> *req);
110   void finish_in_flight_write();
111
112   int start_in_flight_io(AioCompletion *c);
113   void finish_in_flight_io();
114   void fail_in_flight_io(int r, ImageRequest<ImageCtxT> *req);
115
116   void queue(ImageRequest<ImageCtxT> *req);
117
118   void handle_acquire_lock(int r, ImageRequest<ImageCtxT> *req);
119   void handle_refreshed(int r, ImageRequest<ImageCtxT> *req);
120   void handle_blocked_writes(int r);
121 };
122
123 } // namespace io
124 } // namespace librbd
125
126 extern template class librbd::io::ImageRequestWQ<librbd::ImageCtx>;
127
128 #endif // CEPH_LIBRBD_IO_IMAGE_REQUEST_WQ_H