]> git.proxmox.com Git - ceph.git/blob - ceph/src/librbd/operation/Request.h
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / librbd / operation / Request.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_OPERATION_REQUEST_H
5 #define CEPH_LIBRBD_OPERATION_REQUEST_H
6
7 #include "librbd/AsyncRequest.h"
8 #include "include/Context.h"
9 #include "common/RWLock.h"
10 #include "librbd/Utils.h"
11 #include "librbd/Journal.h"
12
13 namespace librbd {
14
15 class ImageCtx;
16
17 namespace operation {
18
19 template <typename ImageCtxT = ImageCtx>
20 class Request : public AsyncRequest<ImageCtxT> {
21 public:
22 Request(ImageCtxT &image_ctx, Context *on_finish,
23 uint64_t journal_op_tid = 0);
24
25 void send();
26
27 protected:
28 void finish(int r) override;
29 virtual void send_op() = 0;
30
31 virtual bool can_affect_io() const {
32 return false;
33 }
34 virtual journal::Event create_event(uint64_t op_tid) const = 0;
35
36 template <typename T, Context*(T::*MF)(int*)>
37 bool append_op_event(T *request) {
38 ImageCtxT &image_ctx = this->m_image_ctx;
39
40 assert(can_affect_io());
41 RWLock::RLocker owner_locker(image_ctx.owner_lock);
42 RWLock::RLocker snap_locker(image_ctx.snap_lock);
43 if (image_ctx.journal != nullptr) {
44 if (image_ctx.journal->is_journal_replaying()) {
45 Context *ctx = util::create_context_callback<T, MF>(request);
46 replay_op_ready(ctx);
47 return true;
48 } else if (image_ctx.journal->is_journal_appending()) {
49 Context *ctx = util::create_context_callback<T, MF>(request);
50 append_op_event(ctx);
51 return true;
52 }
53 }
54 return false;
55 }
56
57 bool append_op_event();
58
59 // NOTE: temporary until converted to new state machine format
60 Context *create_context_finisher(int r);
61 void finish_and_destroy(int r) override;
62
63 private:
64 struct C_AppendOpEvent : public Context {
65 Request *request;
66 Context *on_safe;
67 C_AppendOpEvent(Request *request, Context *on_safe)
68 : request(request), on_safe(on_safe) {
69 }
70 void finish(int r) override {
71 if (r >= 0) {
72 request->m_appended_op_event = true;
73 }
74 on_safe->complete(r);
75 }
76 };
77
78 struct C_CommitOpEvent : public Context {
79 Request *request;
80 int ret_val;
81 C_CommitOpEvent(Request *request, int ret_val)
82 : request(request), ret_val(ret_val) {
83 }
84 void finish(int r) override {
85 request->handle_commit_op_event(r, ret_val);
86 delete request;
87 }
88 };
89
90 uint64_t m_op_tid = 0;
91 bool m_appended_op_event = false;
92 bool m_committed_op_event = false;
93
94 void replay_op_ready(Context *on_safe);
95 void append_op_event(Context *on_safe);
96 void handle_op_event_safe(int r);
97
98 bool commit_op_event(int r);
99 void handle_commit_op_event(int r, int original_ret_val);
100
101 };
102
103 } // namespace operation
104 } // namespace librbd
105
106 extern template class librbd::operation::Request<librbd::ImageCtx>;
107
108 #endif // CEPH_LIBRBD_OPERATION_REQUEST_H