]> git.proxmox.com Git - ceph.git/blob - ceph/src/osd/OpRequest.h
add subtree-ish sources for 12.0.3
[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 uint8_t hit_flag_points;
89 uint8_t latest_flag_point;
90 utime_t dequeued_time;
91 static const uint8_t flag_queued_for_pg=1 << 0;
92 static const uint8_t flag_reached_pg = 1 << 1;
93 static const uint8_t flag_delayed = 1 << 2;
94 static const uint8_t flag_started = 1 << 3;
95 static const uint8_t flag_sub_op_sent = 1 << 4;
96 static const uint8_t flag_commit_sent = 1 << 5;
97
98 std::vector<ClassInfo> classes_;
99
100 OpRequest(Message *req, OpTracker *tracker);
101
102 protected:
103 void _dump_op_descriptor_unlocked(ostream& stream) const override;
104 void _unregistered() override;
105
106 public:
107 ~OpRequest() override {
108 request->put();
109 }
110
111 bool check_send_map = true; ///< true until we check if sender needs a map
112 epoch_t sent_epoch = 0; ///< client's map epoch
113 epoch_t min_epoch = 0; ///< min epoch needed to handle this msg
114
115 bool hitset_inserted;
116 const Message *get_req() const { return request; }
117 Message *get_nonconst_req() { return request; }
118
119 entity_name_t get_source() {
120 if (request) {
121 return request->get_source();
122 } else {
123 return entity_name_t();
124 }
125 }
126
127 const char *state_string() const override {
128 switch(latest_flag_point) {
129 case flag_queued_for_pg: return "queued for pg";
130 case flag_reached_pg: return "reached pg";
131 case flag_delayed: return "delayed";
132 case flag_started: return "started";
133 case flag_sub_op_sent: return "waiting for sub ops";
134 case flag_commit_sent: return "commit sent; apply or cleanup";
135 default: break;
136 }
137 return "no flag points reached";
138 }
139
140 void mark_queued_for_pg() {
141 mark_flag_point(flag_queued_for_pg, "queued_for_pg");
142 }
143 void mark_reached_pg() {
144 mark_flag_point(flag_reached_pg, "reached_pg");
145 }
146 void mark_delayed(const string& s) {
147 mark_flag_point_string(flag_delayed, s);
148 }
149 void mark_started() {
150 mark_flag_point(flag_started, "started");
151 }
152 void mark_sub_op_sent(const string& s) {
153 mark_flag_point_string(flag_sub_op_sent, s);
154 }
155 void mark_commit_sent() {
156 mark_flag_point(flag_commit_sent, "commit_sent");
157 }
158
159 utime_t get_dequeued_time() const {
160 return dequeued_time;
161 }
162 void set_dequeued_time(utime_t deq_time) {
163 dequeued_time = deq_time;
164 }
165
166 osd_reqid_t get_reqid() const {
167 return reqid;
168 }
169
170 typedef boost::intrusive_ptr<OpRequest> Ref;
171
172 private:
173 void set_rmw_flags(int flags);
174 void mark_flag_point(uint8_t flag, const char *s);
175 void mark_flag_point_string(uint8_t flag, const string& s);
176 };
177
178 typedef OpRequest::Ref OpRequestRef;
179
180 ostream& operator<<(ostream& out, const OpRequest::ClassInfo& i);
181
182 #endif /* OPREQUEST_H_ */