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