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 New Dream Network/Sage Weil <sage@newdream.net>
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.
17 #include "osd/osd_op_util.h"
18 #include "osd/osd_types.h"
19 #include "common/TrackedOp.h"
20 #include "common/tracer.h"
22 * The OpRequest takes in a Message* and takes over a single reference
23 * to it, which it puts() when destroyed.
25 struct OpRequest
: public TrackedOp
{
26 friend class OpTracker
;
32 int maybe_init_op_info(const OSDMap
&osdmap
);
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(); }
50 std::vector
<OpInfo::ClassInfo
> classes() const {
51 return op_info
.get_classes();
54 void _dump(ceph::Formatter
*f
) const override
;
56 bool has_feature(uint64_t f
) const {
57 return request
->get_connection()->has_feature(f
);
61 Message
*request
; /// the logical request we are tracking
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;
75 OpRequest(Message
*req
, OpTracker
*tracker
);
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
;
83 ~OpRequest() override
{
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
92 jspan osd_parent_span
;
95 const T
* get_req() const { return static_cast<const T
*>(request
); }
97 const Message
*get_req() const { return request
; }
98 Message
*get_nonconst_req() { return request
; }
100 entity_name_t
get_source() {
102 return request
->get_source();
104 return entity_name_t();
107 uint8_t state_flag() const {
108 return latest_flag_point
;
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";
121 return "no flag points reached";
124 static std::string
get_state_string(uint8_t flag
) {
125 std::string flag_point
;
128 case flag_queued_for_pg
:
129 flag_point
= "queued for pg";
131 case flag_reached_pg
:
132 flag_point
= "reached pg";
135 flag_point
= "delayed";
138 flag_point
= "started";
140 case flag_sub_op_sent
:
141 flag_point
= "waiting for sub ops";
143 case flag_commit_sent
:
144 flag_point
= "commit sent; apply or cleanup";
150 void mark_queued_for_pg() {
151 mark_flag_point(flag_queued_for_pg
, "queued_for_pg");
153 void mark_reached_pg() {
154 mark_flag_point(flag_reached_pg
, "reached_pg");
156 void mark_delayed(const char* s
) {
157 mark_flag_point(flag_delayed
, s
);
159 void mark_started() {
160 mark_flag_point(flag_started
, "started");
162 void mark_sub_op_sent(const std::string
& s
) {
163 mark_flag_point_string(flag_sub_op_sent
, s
);
165 void mark_commit_sent() {
166 mark_flag_point(flag_commit_sent
, "commit_sent");
169 utime_t
get_dequeued_time() const {
170 return dequeued_time
;
172 void set_dequeued_time(utime_t deq_time
) {
173 dequeued_time
= deq_time
;
176 osd_reqid_t
get_reqid() const {
180 typedef boost::intrusive_ptr
<OpRequest
> Ref
;
183 void mark_flag_point(uint8_t flag
, const char *s
);
184 void mark_flag_point_string(uint8_t flag
, const std::string
& s
);
187 typedef OpRequest::Ref OpRequestRef
;
189 #endif /* OPREQUEST_H_ */