]> git.proxmox.com Git - ceph.git/blob - ceph/src/osd/OpRequest.h
update sources to v12.1.2
[ceph.git] / ceph / src / osd / OpRequest.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 New Dream Network/Sage Weil <sage@newdream.net>
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 #ifndef OPREQUEST_H_
15 #define OPREQUEST_H_
16 #include <sstream>
17 #include <stdint.h>
18 #include <vector>
19
20 #include <include/utime.h>
21 #include "common/Mutex.h"
22 #include "include/xlist.h"
23 #include "msg/Message.h"
24 #include "include/memory.h"
25 #include "osd/osd_types.h"
26 #include "common/TrackedOp.h"
27
28 /**
29 * The OpRequest takes in a Message* and takes over a single reference
30 * to it, which it puts() when destroyed.
31 */
32 struct OpRequest : public TrackedOp {
33 friend class OpTracker;
34
35 // rmw flags
36 int rmw_flags;
37
38 bool check_rmw(int flag);
39 bool may_read();
40 bool may_write();
41 bool may_cache();
42 bool rwordered_forced();
43 bool rwordered();
44 bool includes_pg_op();
45 bool need_read_cap();
46 bool need_write_cap();
47 bool need_promote();
48 bool need_skip_handle_cache();
49 bool need_skip_promote();
50 void set_read();
51 void set_write();
52 void set_cache();
53 void set_class_read();
54 void set_class_write();
55 void set_pg_op();
56 void set_promote();
57 void set_skip_handle_cache();
58 void set_skip_promote();
59 void set_force_rwordered();
60
61 struct ClassInfo {
62 ClassInfo(const std::string& name, bool read, bool write,
63 bool whitelisted) :
64 name(name), read(read), write(write), whitelisted(whitelisted)
65 {}
66 const std::string name;
67 const bool read, write, whitelisted;
68 };
69
70 void add_class(const std::string& name, bool read, bool write,
71 bool whitelisted) {
72 classes_.emplace_back(name, read, write, whitelisted);
73 }
74
75 std::vector<ClassInfo> classes() const {
76 return classes_;
77 }
78
79 void _dump(Formatter *f) const override;
80
81 bool has_feature(uint64_t f) const {
82 return request->get_connection()->has_feature(f);
83 }
84
85 private:
86 Message *request; /// the logical request we are tracking
87 osd_reqid_t reqid;
88 entity_inst_t req_src_inst;
89 uint8_t hit_flag_points;
90 uint8_t latest_flag_point;
91 utime_t dequeued_time;
92 static const uint8_t flag_queued_for_pg=1 << 0;
93 static const uint8_t flag_reached_pg = 1 << 1;
94 static const uint8_t flag_delayed = 1 << 2;
95 static const uint8_t flag_started = 1 << 3;
96 static const uint8_t flag_sub_op_sent = 1 << 4;
97 static const uint8_t flag_commit_sent = 1 << 5;
98
99 std::vector<ClassInfo> classes_;
100
101 OpRequest(Message *req, OpTracker *tracker);
102
103 protected:
104 void _dump_op_descriptor_unlocked(ostream& stream) const override;
105 void _unregistered() override;
106 bool filter_out(const set<string>& filters) override;
107
108 public:
109 ~OpRequest() override {
110 request->put();
111 }
112
113 bool check_send_map = true; ///< true until we check if sender needs a map
114 epoch_t sent_epoch = 0; ///< client's map epoch
115 epoch_t min_epoch = 0; ///< min epoch needed to handle this msg
116
117 bool hitset_inserted;
118 const Message *get_req() const { return request; }
119 Message *get_nonconst_req() { return request; }
120
121 entity_name_t get_source() {
122 if (request) {
123 return request->get_source();
124 } else {
125 return entity_name_t();
126 }
127 }
128
129 const char *state_string() const override {
130 switch(latest_flag_point) {
131 case flag_queued_for_pg: return "queued for pg";
132 case flag_reached_pg: return "reached pg";
133 case flag_delayed: return "delayed";
134 case flag_started: return "started";
135 case flag_sub_op_sent: return "waiting for sub ops";
136 case flag_commit_sent: return "commit sent; apply or cleanup";
137 default: break;
138 }
139 return "no flag points reached";
140 }
141
142 void mark_queued_for_pg() {
143 mark_flag_point(flag_queued_for_pg, "queued_for_pg");
144 }
145 void mark_reached_pg() {
146 mark_flag_point(flag_reached_pg, "reached_pg");
147 }
148 void mark_delayed(const string& s) {
149 mark_flag_point_string(flag_delayed, s);
150 }
151 void mark_started() {
152 mark_flag_point(flag_started, "started");
153 }
154 void mark_sub_op_sent(const string& s) {
155 mark_flag_point_string(flag_sub_op_sent, s);
156 }
157 void mark_commit_sent() {
158 mark_flag_point(flag_commit_sent, "commit_sent");
159 }
160
161 utime_t get_dequeued_time() const {
162 return dequeued_time;
163 }
164 void set_dequeued_time(utime_t deq_time) {
165 dequeued_time = deq_time;
166 }
167
168 osd_reqid_t get_reqid() const {
169 return reqid;
170 }
171
172 typedef boost::intrusive_ptr<OpRequest> Ref;
173
174 private:
175 void set_rmw_flags(int flags);
176 void mark_flag_point(uint8_t flag, const char *s);
177 void mark_flag_point_string(uint8_t flag, const string& s);
178 };
179
180 typedef OpRequest::Ref OpRequestRef;
181
182 ostream& operator<<(ostream& out, const OpRequest::ClassInfo& i);
183
184 #endif /* OPREQUEST_H_ */