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