]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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-2006 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 | ||
15 | ||
16 | #ifndef CEPH_MDISCOVERREPLY_H | |
17 | #define CEPH_MDISCOVERREPLY_H | |
18 | ||
19 | #include "msg/Message.h" | |
20 | #include "include/filepath.h" | |
21 | ||
22 | #include <string> | |
23 | ||
24 | ||
25 | ||
26 | /** | |
27 | * MDiscoverReply - return new replicas (of inodes, dirs, dentries) | |
28 | * | |
29 | * we group returned items by (dir, dentry, inode). each | |
30 | * item in each set shares an index (it's "depth"). | |
31 | * | |
32 | * we can start and end with any type. | |
33 | * no_base_dir = true if the first group has an inode but no dir | |
34 | * no_base_dentry = true if the first group has an inode but no dentry | |
35 | * they are false if there is no returned data, ie the first group is empty. | |
36 | * | |
37 | * we also return errors: | |
38 | * error_flag_dn(std::string) - the specified dentry dne | |
39 | * error_flag_dir - the last item wasn't a dir, so we couldn't continue. | |
40 | * | |
41 | * and sometimes, | |
42 | * dir_auth_hint - where we think the dir auth is | |
43 | * | |
44 | * depth() gives us the number of depth units/indices for which we have | |
45 | * information. this INCLUDES those for which we have errors but no data. | |
46 | * | |
47 | * see MDCache::handle_discover, handle_discover_reply. | |
48 | * | |
49 | * | |
50 | * so basically, we get | |
51 | * | |
52 | * dir den ino i | |
53 | * x 0 | |
54 | * x x x 1 | |
55 | * or | |
56 | * x x 0 | |
57 | * x x x 1 | |
58 | * or | |
59 | * x x x 0 | |
60 | * x x x 1 | |
61 | * ...and trail off however we want. | |
62 | * | |
63 | * | |
64 | */ | |
65 | ||
66 | class MDiscoverReply : public Message { | |
67 | ||
68 | static const int HEAD_VERSION = 2; | |
69 | ||
70 | // info about original request | |
71 | inodeno_t base_ino; | |
72 | frag_t base_dir_frag; | |
73 | bool wanted_base_dir; | |
74 | bool wanted_xlocked; | |
75 | snapid_t wanted_snapid; | |
76 | ||
77 | // and the response | |
78 | bool flag_error_dn; | |
79 | bool flag_error_dir; | |
80 | std::string error_dentry; // dentry that was not found (to trigger waiters on asker) | |
81 | bool unsolicited; | |
82 | ||
83 | mds_rank_t dir_auth_hint; | |
84 | ||
85 | public: | |
86 | __u8 starts_with; | |
87 | bufferlist trace; | |
88 | ||
89 | enum { DIR, DENTRY, INODE }; | |
90 | ||
91 | // accessors | |
92 | inodeno_t get_base_ino() { return base_ino; } | |
93 | frag_t get_base_dir_frag() { return base_dir_frag; } | |
94 | bool get_wanted_base_dir() { return wanted_base_dir; } | |
95 | bool get_wanted_xlocked() { return wanted_xlocked; } | |
96 | snapid_t get_wanted_snapid() { return wanted_snapid; } | |
97 | ||
98 | bool is_flag_error_dn() { return flag_error_dn; } | |
99 | bool is_flag_error_dir() { return flag_error_dir; } | |
94b18763 | 100 | const std::string& get_error_dentry() { return error_dentry; } |
7c673cae FG |
101 | |
102 | int get_starts_with() { return starts_with; } | |
103 | ||
104 | mds_rank_t get_dir_auth_hint() const { return dir_auth_hint; } | |
105 | ||
106 | bool is_unsolicited() { return unsolicited; } | |
107 | void mark_unsolicited() { unsolicited = true; } | |
108 | ||
109 | void set_base_dir_frag(frag_t df) { base_dir_frag = df; } | |
110 | ||
111 | // cons | |
112 | MDiscoverReply() : Message(MSG_MDS_DISCOVERREPLY, HEAD_VERSION) { } | |
113 | MDiscoverReply(MDiscover *dis) : | |
114 | Message(MSG_MDS_DISCOVERREPLY, HEAD_VERSION), | |
115 | base_ino(dis->get_base_ino()), | |
116 | base_dir_frag(dis->get_base_dir_frag()), | |
117 | wanted_base_dir(dis->wants_base_dir()), | |
118 | wanted_xlocked(dis->wants_xlocked()), | |
119 | wanted_snapid(dis->get_snapid()), | |
120 | flag_error_dn(false), | |
121 | flag_error_dir(false), | |
122 | unsolicited(false), | |
123 | dir_auth_hint(CDIR_AUTH_UNKNOWN), | |
124 | starts_with(DIR) | |
125 | { | |
126 | header.tid = dis->get_tid(); | |
127 | } | |
128 | MDiscoverReply(dirfrag_t df) : | |
129 | Message(MSG_MDS_DISCOVERREPLY, HEAD_VERSION), | |
130 | base_ino(df.ino), | |
131 | base_dir_frag(df.frag), | |
132 | wanted_base_dir(false), | |
133 | wanted_xlocked(false), | |
134 | wanted_snapid(CEPH_NOSNAP), | |
135 | flag_error_dn(false), | |
136 | flag_error_dir(false), | |
137 | unsolicited(false), | |
138 | dir_auth_hint(CDIR_AUTH_UNKNOWN), | |
139 | starts_with(DIR) | |
140 | { | |
141 | header.tid = 0; | |
142 | } | |
143 | private: | |
144 | ~MDiscoverReply() override {} | |
145 | ||
146 | public: | |
147 | const char *get_type_name() const override { return "discover_reply"; } | |
148 | void print(ostream& out) const override { | |
149 | out << "discover_reply(" << header.tid << " " << base_ino << ")"; | |
150 | } | |
151 | ||
152 | // builders | |
153 | bool is_empty() { | |
154 | return trace.length() == 0 && | |
155 | !flag_error_dn && | |
156 | !flag_error_dir && | |
157 | dir_auth_hint == CDIR_AUTH_UNKNOWN; | |
158 | } | |
159 | ||
160 | // void set_flag_forward() { flag_forward = true; } | |
94b18763 | 161 | void set_flag_error_dn(boost::string_view dn) { |
7c673cae | 162 | flag_error_dn = true; |
94b18763 | 163 | error_dentry = std::string(dn); |
7c673cae FG |
164 | } |
165 | void set_flag_error_dir() { | |
166 | flag_error_dir = true; | |
167 | } | |
168 | void set_dir_auth_hint(int a) { | |
169 | dir_auth_hint = a; | |
170 | } | |
94b18763 FG |
171 | void set_error_dentry(boost::string_view dn) { |
172 | error_dentry = std::string(dn); | |
7c673cae FG |
173 | } |
174 | ||
175 | ||
176 | // ... | |
177 | void decode_payload() override { | |
178 | bufferlist::iterator p = payload.begin(); | |
179 | ::decode(base_ino, p); | |
180 | ::decode(base_dir_frag, p); | |
181 | ::decode(wanted_base_dir, p); | |
182 | ::decode(wanted_xlocked, p); | |
183 | ::decode(wanted_snapid, p); | |
184 | ::decode(flag_error_dn, p); | |
185 | ::decode(flag_error_dir, p); | |
186 | ::decode(error_dentry, p); | |
187 | ::decode(dir_auth_hint, p); | |
188 | ::decode(unsolicited, p); | |
189 | ||
190 | ::decode(starts_with, p); | |
191 | ::decode(trace, p); | |
192 | } | |
193 | void encode_payload(uint64_t features) override { | |
194 | ::encode(base_ino, payload); | |
195 | ::encode(base_dir_frag, payload); | |
196 | ::encode(wanted_base_dir, payload); | |
197 | ::encode(wanted_xlocked, payload); | |
198 | ::encode(wanted_snapid, payload); | |
199 | ::encode(flag_error_dn, payload); | |
200 | ::encode(flag_error_dir, payload); | |
201 | ::encode(error_dentry, payload); | |
202 | ::encode(dir_auth_hint, payload); | |
203 | ::encode(unsolicited, payload); | |
204 | ||
205 | ::encode(starts_with, payload); | |
206 | ::encode(trace, payload); | |
207 | } | |
208 | }; | |
209 | ||
210 | #endif |