]> git.proxmox.com Git - ceph.git/blob - ceph/src/mds/MDSContext.h
update sources to 12.2.10
[ceph.git] / ceph / src / mds / MDSContext.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2012 Red Hat
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15
16 #ifndef MDS_CONTEXT_H
17 #define MDS_CONTEXT_H
18
19 #include "include/Context.h"
20 #include "include/elist.h"
21 #include "common/ceph_time.h"
22 #include "common/simple_spin.h"
23
24 class MDSRank;
25
26
27 /**
28 * Completion which has access to a reference to the global MDS instance.
29 *
30 * This class exists so that Context subclasses can provide the MDS pointer
31 * from a pointer they already had, e.g. MDCache or Locker, rather than
32 * necessarily having to carry around an extra MDS* pointer.
33 */
34 class MDSContext : public Context
35 {
36 protected:
37 virtual MDSRank *get_mds() = 0;
38 };
39
40
41 /**
42 * A context which must be called with the big MDS lock held. Subclass
43 * this with a get_mds implementation.
44 */
45 class MDSInternalContextBase : public MDSContext
46 {
47 public:
48 void complete(int r) override;
49 };
50
51 /**
52 * General purpose, lets you pass in an MDS pointer.
53 */
54 class MDSInternalContext : public MDSInternalContextBase
55 {
56 protected:
57 MDSRank *mds;
58 MDSRank* get_mds() override;
59
60 public:
61 explicit MDSInternalContext(MDSRank *mds_) : mds(mds_) {
62 assert(mds != NULL);
63 }
64 };
65
66 /**
67 * Wrap a regular Context up as an Internal context. Useful
68 * if you're trying to work with one of our more generic frameworks.
69 */
70 class MDSInternalContextWrapper : public MDSInternalContextBase
71 {
72 protected:
73 MDSRank *mds;
74 Context *fin;
75 MDSRank *get_mds() override;
76 void finish(int r) override;
77 public:
78 MDSInternalContextWrapper(MDSRank *m, Context *c) : mds(m), fin(c) {}
79 };
80
81 class MDSIOContextBase : public MDSContext
82 {
83 public:
84 MDSIOContextBase(bool track=true);
85 virtual ~MDSIOContextBase();
86 MDSIOContextBase(const MDSIOContextBase&) = delete;
87 MDSIOContextBase& operator=(const MDSIOContextBase&) = delete;
88
89 void complete(int r) override;
90
91 virtual void print(ostream& out) const = 0;
92
93 static bool check_ios_in_flight(ceph::coarse_mono_time cutoff,
94 std::string& slow_count,
95 ceph::coarse_mono_time& oldest);
96 private:
97 ceph::coarse_mono_time created_at;
98 elist<MDSIOContextBase*>::item list_item;
99
100 static elist<MDSIOContextBase*> ctx_list;
101 static std::atomic_flag ctx_list_lock;
102 };
103
104 /**
105 * Completion for an log operation, takes big MDSRank lock
106 * before executing finish function. Update log's safe pos
107 * after finish functuon return.
108 */
109 class MDSLogContextBase : public MDSIOContextBase
110 {
111 protected:
112 uint64_t write_pos;
113 public:
114 MDSLogContextBase() : write_pos(0) {}
115 void complete(int r) final;
116 void set_write_pos(uint64_t wp) { write_pos = wp; }
117 virtual void pre_finish(int r) {}
118 void print(ostream& out) const override {
119 out << "log_event(" << write_pos << ")";
120 }
121 };
122
123 /**
124 * Completion for an I/O operation, takes big MDSRank lock
125 * before executing finish function.
126 */
127 class MDSIOContext : public MDSIOContextBase
128 {
129 protected:
130 MDSRank *mds;
131 MDSRank* get_mds() override;
132
133 public:
134 explicit MDSIOContext(MDSRank *mds_) : mds(mds_) {
135 assert(mds != NULL);
136 }
137 };
138
139 /**
140 * Wrap a regular Context up as an IO Context. Useful
141 * if you're trying to work with one of our more generic frameworks.
142 */
143 class MDSIOContextWrapper : public MDSIOContextBase
144 {
145 protected:
146 MDSRank *mds;
147 Context *fin;
148 MDSRank *get_mds() override;
149 public:
150 MDSIOContextWrapper(MDSRank *m, Context *c) : mds(m), fin(c) {}
151 void finish(int r) override;
152 void print(ostream& out) const override {
153 out << "io_context_wrapper(" << fin << ")";
154 }
155 };
156
157 /**
158 * No-op for callers expecting MDSInternalContextBase
159 */
160 class C_MDSInternalNoop final : public MDSInternalContextBase
161 {
162 MDSRank* get_mds() override {ceph_abort();}
163 public:
164 void finish(int r) override {}
165 void complete(int r) override { delete this; }
166 };
167
168
169 /**
170 * This class is used where you have an MDSInternalContextBase but
171 * you sometimes want to call it back from an I/O completion.
172 */
173 class C_IO_Wrapper : public MDSIOContext
174 {
175 protected:
176 bool async;
177 MDSInternalContextBase *wrapped;
178 void finish(int r) override {
179 wrapped->complete(r);
180 wrapped = nullptr;
181 }
182 public:
183 C_IO_Wrapper(MDSRank *mds_, MDSInternalContextBase *wrapped_) :
184 MDSIOContext(mds_), async(true), wrapped(wrapped_) {
185 assert(wrapped != NULL);
186 }
187
188 ~C_IO_Wrapper() override {
189 if (wrapped != nullptr) {
190 delete wrapped;
191 wrapped = nullptr;
192 }
193 }
194 void complete(int r) final;
195 void print(ostream& out) const override {
196 out << "io_wrapper(" << wrapped << ")";
197 }
198 };
199
200
201 /**
202 * Gather needs a default-constructable class
203 */
204 class MDSInternalContextGather : public MDSInternalContextBase
205 {
206 protected:
207 MDSRank *get_mds() override;
208 };
209
210
211 class MDSGather : public C_GatherBase<MDSInternalContextBase, MDSInternalContextGather>
212 {
213 public:
214 MDSGather(CephContext *cct, MDSInternalContextBase *onfinish) : C_GatherBase<MDSInternalContextBase, MDSInternalContextGather>(cct, onfinish) {}
215 protected:
216 MDSRank *get_mds() override {return NULL;}
217 };
218
219
220 typedef C_GatherBuilderBase<MDSInternalContextBase, MDSGather> MDSGatherBuilder;
221
222 #endif // MDS_CONTEXT_H