Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / 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_ */