Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / 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
21 class MDSRank;
22
23
24 /**
25  * Completion which has access to a reference to the global MDS instance.
26  *
27  * This class exists so that Context subclasses can provide the MDS pointer
28  * from a pointer they already had, e.g. MDCache or Locker, rather than
29  * necessarily having to carry around an extra MDS* pointer. 
30  */
31 class MDSContext : public Context
32 {
33 protected:
34   virtual MDSRank *get_mds() = 0;
35 };
36
37
38 /**
39  * A context which must be called with the big MDS lock held.  Subclass
40  * this with a get_mds implementation.
41  */
42 class MDSInternalContextBase : public MDSContext
43 {
44 public:
45     void complete(int r) override;
46 };
47
48 /**
49  * General purpose, lets you pass in an MDS pointer.
50  */
51 class MDSInternalContext : public MDSInternalContextBase
52 {
53 protected:
54   MDSRank *mds;
55   MDSRank* get_mds() override;
56
57 public:
58   explicit MDSInternalContext(MDSRank *mds_) : mds(mds_) {
59     assert(mds != NULL);
60   }
61 };
62
63 /**
64  * Wrap a regular Context up as an Internal context. Useful
65  * if you're trying to work with one of our more generic frameworks.
66  */
67 class MDSInternalContextWrapper : public MDSInternalContextBase
68 {
69 protected:
70   MDSRank *mds;
71   Context *fin;
72   MDSRank *get_mds() override;
73 public:
74   MDSInternalContextWrapper(MDSRank *m, Context *c) : mds(m), fin(c) {}
75   void finish(int r) override;
76 };
77
78 class MDSIOContextBase : public MDSContext
79 {
80 public:
81   void complete(int r) override;
82 };
83
84 /**
85  * Completion for an log operation, takes big MDSRank lock
86  * before executing finish function. Update log's safe pos
87  * after finish functuon return.
88  */
89 class MDSLogContextBase : public MDSIOContextBase
90 {
91 protected:
92   uint64_t write_pos;
93 public:
94   MDSLogContextBase() : write_pos(0) {}
95   void complete(int r) final;
96   void set_write_pos(uint64_t wp) { write_pos = wp; }
97   virtual void pre_finish(int r) {}
98 };
99
100 /**
101  * Completion for an I/O operation, takes big MDSRank lock
102  * before executing finish function.
103  */
104 class MDSIOContext : public MDSIOContextBase
105 {
106 protected:
107   MDSRank *mds;
108   MDSRank* get_mds() override;
109
110 public:
111   explicit MDSIOContext(MDSRank *mds_) : mds(mds_) {
112     assert(mds != NULL);
113   }
114 };
115
116 /**
117  * Wrap a regular Context up as an IO Context. Useful
118  * if you're trying to work with one of our more generic frameworks.
119  */
120 class MDSIOContextWrapper : public MDSIOContextBase
121 {
122 protected:
123   MDSRank *mds;
124   Context *fin;
125   MDSRank *get_mds() override;
126 public:
127   MDSIOContextWrapper(MDSRank *m, Context *c) : mds(m), fin(c) {}
128   void finish(int r) override;
129 };
130
131 /**
132  * No-op for callers expecting MDSInternalContextBase
133  */
134 class C_MDSInternalNoop final : public MDSInternalContextBase
135 {
136   MDSRank* get_mds() override {ceph_abort();}
137 public:
138   void finish(int r) override {}
139   void complete(int r) override { delete this; }
140 };
141
142
143 /**
144  * This class is used where you have an MDSInternalContextBase but
145  * you sometimes want to call it back from an I/O completion.
146  */
147 class C_IO_Wrapper : public MDSIOContext
148 {
149 protected:
150   bool async;
151   MDSInternalContextBase *wrapped;
152   void finish(int r) override {
153     wrapped->complete(r);
154     wrapped = nullptr;
155   }
156 public:
157   C_IO_Wrapper(MDSRank *mds_, MDSInternalContextBase *wrapped_) :
158     MDSIOContext(mds_), async(true), wrapped(wrapped_) {
159     assert(wrapped != NULL);
160   }
161
162   ~C_IO_Wrapper() override {
163     if (wrapped != nullptr) {
164       delete wrapped;
165       wrapped = nullptr;
166     }
167   }
168   void complete(int r) final;
169 };
170
171
172 /**
173  * Gather needs a default-constructable class
174  */
175 class MDSInternalContextGather : public MDSInternalContextBase
176 {
177 protected:
178   MDSRank *get_mds() override;
179 };
180
181
182 class MDSGather : public C_GatherBase<MDSInternalContextBase, MDSInternalContextGather>
183 {
184 public:
185   MDSGather(CephContext *cct, MDSInternalContextBase *onfinish) : C_GatherBase<MDSInternalContextBase, MDSInternalContextGather>(cct, onfinish) {}
186 protected:
187   MDSRank *get_mds() override {return NULL;}
188 };
189
190
191 typedef C_GatherBuilderBase<MDSInternalContextBase, MDSGather> MDSGatherBuilder;
192
193 #endif  // MDS_CONTEXT_H