]> git.proxmox.com Git - ceph.git/blob - ceph/src/messages/MForward.h
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / messages / MForward.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) 2004-2010 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 * Client requests often need to get forwarded from some monitor
14 * to the leader. This class encapsulates the original message
15 * along with the client's caps so the leader can do proper permissions
16 * checking.
17 */
18
19 #ifndef CEPH_MFORWARD_H
20 #define CEPH_MFORWARD_H
21
22 #include "msg/Message.h"
23 #include "mon/MonCap.h"
24 #include "include/encoding.h"
25 #include "include/stringify.h"
26
27 struct MForward : public Message {
28 uint64_t tid;
29 entity_inst_t client;
30 MonCap client_caps;
31 uint64_t con_features;
32 EntityName entity_name;
33 PaxosServiceMessage *msg; // incoming or outgoing message
34
35 string msg_desc; // for operator<< only
36
37 static const int HEAD_VERSION = 3;
38 static const int COMPAT_VERSION = 3;
39
40 MForward() : Message(MSG_FORWARD, HEAD_VERSION, COMPAT_VERSION),
41 tid(0), con_features(0), msg(NULL) {}
42 //the message needs to have caps filled in!
43 MForward(uint64_t t, PaxosServiceMessage *m, uint64_t feat) :
44 Message(MSG_FORWARD, HEAD_VERSION, COMPAT_VERSION),
45 tid(t), msg(NULL) {
46 client = m->get_source_inst();
47 client_caps = m->get_session()->caps;
48 con_features = feat;
49 // we may need to reencode for the target mon
50 msg->clear_payload();
51 msg = (PaxosServiceMessage*)m->get();
52 }
53 MForward(uint64_t t, PaxosServiceMessage *m, uint64_t feat,
54 const MonCap& caps) :
55 Message(MSG_FORWARD, HEAD_VERSION, COMPAT_VERSION),
56 tid(t), client_caps(caps), msg(NULL) {
57 client = m->get_source_inst();
58 con_features = feat;
59 msg = (PaxosServiceMessage*)m->get();
60 }
61 private:
62 ~MForward() override {
63 if (msg) {
64 // message was unclaimed
65 msg->put();
66 msg = NULL;
67 }
68 }
69
70 public:
71 void encode_payload(uint64_t features) override {
72 ::encode(tid, payload);
73 ::encode(client, payload, features);
74 ::encode(client_caps, payload, features);
75 // Encode client message with intersection of target and source
76 // features. This could matter if the semantics of the encoded
77 // message are changed when reencoding with more features than the
78 // client had originally. That should never happen, but we may as
79 // well be defensive here.
80 if (con_features != features) {
81 msg->clear_payload();
82 }
83 encode_message(msg, features & con_features, payload);
84 ::encode(con_features, payload);
85 ::encode(entity_name, payload);
86 }
87
88 void decode_payload() override {
89 bufferlist::iterator p = payload.begin();
90 ::decode(tid, p);
91 ::decode(client, p);
92 ::decode(client_caps, p);
93 msg = (PaxosServiceMessage *)decode_message(NULL, 0, p);
94 ::decode(con_features, p);
95 ::decode(entity_name, p);
96 }
97
98 PaxosServiceMessage *claim_message() {
99 // let whoever is claiming the message deal with putting it.
100 assert(msg);
101 msg_desc = stringify(*msg);
102 PaxosServiceMessage *m = msg;
103 msg = NULL;
104 return m;
105 }
106
107 const char *get_type_name() const override { return "forward"; }
108 void print(ostream& o) const override {
109 o << "forward(";
110 if (msg) {
111 o << *msg;
112 } else {
113 o << msg_desc;
114 }
115 o << " caps " << client_caps
116 << " tid " << tid
117 << " con_features " << con_features << ")";
118 }
119 };
120
121 #endif