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