1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2012 Red Hat
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.
19 #include "include/Context.h"
20 #include "include/elist.h"
21 #include "common/ceph_time.h"
22 #include "common/simple_spin.h"
28 * Completion which has access to a reference to the global MDS instance.
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.
34 class MDSContext
: public Context
37 virtual MDSRank
*get_mds() = 0;
42 * A context which must be called with the big MDS lock held. Subclass
43 * this with a get_mds implementation.
45 class MDSInternalContextBase
: public MDSContext
48 void complete(int r
) override
;
52 * General purpose, lets you pass in an MDS pointer.
54 class MDSInternalContext
: public MDSInternalContextBase
58 MDSRank
* get_mds() override
;
61 explicit MDSInternalContext(MDSRank
*mds_
) : mds(mds_
) {
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.
70 class MDSInternalContextWrapper
: public MDSInternalContextBase
75 MDSRank
*get_mds() override
;
76 void finish(int r
) override
;
78 MDSInternalContextWrapper(MDSRank
*m
, Context
*c
) : mds(m
), fin(c
) {}
81 class MDSIOContextBase
: public MDSContext
84 MDSIOContextBase(bool track
=true);
85 virtual ~MDSIOContextBase();
86 MDSIOContextBase(const MDSIOContextBase
&) = delete;
87 MDSIOContextBase
& operator=(const MDSIOContextBase
&) = delete;
89 void complete(int r
) override
;
91 virtual void print(ostream
& out
) const = 0;
93 static bool check_ios_in_flight(ceph::coarse_mono_time cutoff
,
94 std::string
& slow_count
,
95 ceph::coarse_mono_time
& oldest
);
97 ceph::coarse_mono_time created_at
;
98 elist
<MDSIOContextBase
*>::item list_item
;
100 static elist
<MDSIOContextBase
*> ctx_list
;
101 static std::atomic_flag ctx_list_lock
;
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.
109 class MDSLogContextBase
: public MDSIOContextBase
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
<< ")";
124 * Completion for an I/O operation, takes big MDSRank lock
125 * before executing finish function.
127 class MDSIOContext
: public MDSIOContextBase
131 MDSRank
* get_mds() override
;
134 explicit MDSIOContext(MDSRank
*mds_
) : mds(mds_
) {
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.
143 class MDSIOContextWrapper
: public MDSIOContextBase
148 MDSRank
*get_mds() override
;
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
<< ")";
158 * No-op for callers expecting MDSInternalContextBase
160 class C_MDSInternalNoop final
: public MDSInternalContextBase
162 MDSRank
* get_mds() override
{ceph_abort();}
164 void finish(int r
) override
{}
165 void complete(int r
) override
{ delete this; }
170 * This class is used where you have an MDSInternalContextBase but
171 * you sometimes want to call it back from an I/O completion.
173 class C_IO_Wrapper
: public MDSIOContext
177 MDSInternalContextBase
*wrapped
;
178 void finish(int r
) override
{
179 wrapped
->complete(r
);
183 C_IO_Wrapper(MDSRank
*mds_
, MDSInternalContextBase
*wrapped_
) :
184 MDSIOContext(mds_
), async(true), wrapped(wrapped_
) {
185 assert(wrapped
!= NULL
);
188 ~C_IO_Wrapper() override
{
189 if (wrapped
!= nullptr) {
194 void complete(int r
) final
;
195 void print(ostream
& out
) const override
{
196 out
<< "io_wrapper(" << wrapped
<< ")";
202 * Gather needs a default-constructable class
204 class MDSInternalContextGather
: public MDSInternalContextBase
207 MDSRank
*get_mds() override
;
211 class MDSGather
: public C_GatherBase
<MDSInternalContextBase
, MDSInternalContextGather
>
214 MDSGather(CephContext
*cct
, MDSInternalContextBase
*onfinish
) : C_GatherBase
<MDSInternalContextBase
, MDSInternalContextGather
>(cct
, onfinish
) {}
216 MDSRank
*get_mds() override
{return NULL
;}
220 typedef C_GatherBuilderBase
<MDSInternalContextBase
, MDSGather
> MDSGatherBuilder
;
222 #endif // MDS_CONTEXT_H