]>
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_MCLIENTREPLY_H | |
17 | #define CEPH_MCLIENTREPLY_H | |
18 | ||
19 | #include "include/types.h" | |
20 | #include "include/fs_types.h" | |
21 | #include "MClientRequest.h" | |
22 | ||
23 | #include "msg/Message.h" | |
24 | #include "include/ceph_features.h" | |
25 | #include "common/errno.h" | |
26 | ||
27 | /*** | |
28 | * | |
29 | * MClientReply - container message for MDS reply to a client's MClientRequest | |
30 | * | |
31 | * key fields: | |
32 | * long tid - transaction id, so the client can match up with pending request | |
33 | * int result - error code, or fh if it was open | |
34 | * | |
35 | * for most requests: | |
36 | * trace is a vector of InodeStat's tracing from root to the file/dir/whatever | |
37 | * the operation referred to, so that the client can update it's info about what | |
38 | * metadata lives on what MDS. | |
39 | * | |
40 | * for readdir replies: | |
41 | * dir_contents is a vector of InodeStat*'s. | |
42 | * | |
43 | * that's mostly it, i think! | |
44 | * | |
45 | */ | |
46 | ||
47 | ||
48 | struct LeaseStat { | |
49 | // this matches ceph_mds_reply_lease | |
50 | __u16 mask; | |
51 | __u32 duration_ms; | |
52 | __u32 seq; | |
53 | ||
54 | LeaseStat() : mask(0), duration_ms(0), seq(0) {} | |
55 | ||
56 | void encode(bufferlist &bl) const { | |
57 | ::encode(mask, bl); | |
58 | ::encode(duration_ms, bl); | |
59 | ::encode(seq, bl); | |
60 | } | |
61 | void decode(bufferlist::iterator &bl) { | |
62 | ::decode(mask, bl); | |
63 | ::decode(duration_ms, bl); | |
64 | ::decode(seq, bl); | |
65 | } | |
66 | }; | |
67 | WRITE_CLASS_ENCODER(LeaseStat) | |
68 | ||
69 | inline ostream& operator<<(ostream& out, const LeaseStat& l) { | |
70 | return out << "lease(mask " << l.mask << " dur " << l.duration_ms << ")"; | |
71 | } | |
72 | ||
73 | struct DirStat { | |
74 | // mds distribution hints | |
75 | frag_t frag; | |
76 | __s32 auth; | |
77 | set<__s32> dist; | |
78 | ||
79 | DirStat() : auth(CDIR_AUTH_PARENT) {} | |
80 | DirStat(bufferlist::iterator& p) { | |
81 | decode(p); | |
82 | } | |
83 | ||
84 | void encode(bufferlist& bl) { | |
85 | ::encode(frag, bl); | |
86 | ::encode(auth, bl); | |
87 | ::encode(dist, bl); | |
88 | } | |
89 | void decode(bufferlist::iterator& p) { | |
90 | ::decode(frag, p); | |
91 | ::decode(auth, p); | |
92 | ::decode(dist, p); | |
93 | } | |
94 | ||
95 | // see CDir::encode_dirstat for encoder. | |
96 | }; | |
97 | ||
98 | struct InodeStat { | |
99 | vinodeno_t vino; | |
100 | uint32_t rdev; | |
101 | version_t version; | |
102 | version_t xattr_version; | |
103 | ceph_mds_reply_cap cap; | |
104 | file_layout_t layout; | |
105 | utime_t ctime, btime, mtime, atime; | |
106 | uint32_t time_warp_seq; | |
107 | uint64_t size, max_size; | |
108 | uint64_t change_attr; | |
109 | uint64_t truncate_size; | |
110 | uint32_t truncate_seq; | |
111 | uint32_t mode, uid, gid, nlink; | |
112 | frag_info_t dirstat; | |
113 | nest_info_t rstat; | |
114 | ||
115 | fragtree_t dirfragtree; | |
116 | string symlink; // symlink content (if symlink) | |
117 | ||
118 | ceph_dir_layout dir_layout; | |
119 | ||
120 | bufferlist xattrbl; | |
121 | ||
122 | bufferlist inline_data; | |
123 | version_t inline_version; | |
124 | ||
125 | quota_info_t quota; | |
126 | ||
127 | public: | |
128 | InodeStat() {} | |
129 | InodeStat(bufferlist::iterator& p, uint64_t features) { | |
130 | decode(p, features); | |
131 | } | |
132 | ||
133 | void decode(bufferlist::iterator &p, uint64_t features) { | |
134 | ::decode(vino.ino, p); | |
135 | ::decode(vino.snapid, p); | |
136 | ::decode(rdev, p); | |
137 | ::decode(version, p); | |
138 | ::decode(xattr_version, p); | |
139 | ::decode(cap, p); | |
140 | { | |
141 | ceph_file_layout legacy_layout; | |
142 | ::decode(legacy_layout, p); | |
143 | layout.from_legacy(legacy_layout); | |
144 | } | |
145 | ::decode(ctime, p); | |
146 | ::decode(mtime, p); | |
147 | ::decode(atime, p); | |
148 | ::decode(time_warp_seq, p); | |
149 | ::decode(size, p); | |
150 | ::decode(max_size, p); | |
151 | ::decode(truncate_size, p); | |
152 | ::decode(truncate_seq, p); | |
153 | ::decode(mode, p); | |
154 | ::decode(uid, p); | |
155 | ::decode(gid, p); | |
156 | ::decode(nlink, p); | |
157 | ::decode(dirstat.nfiles, p); | |
158 | ::decode(dirstat.nsubdirs, p); | |
159 | ::decode(rstat.rbytes, p); | |
160 | ::decode(rstat.rfiles, p); | |
161 | ::decode(rstat.rsubdirs, p); | |
162 | ::decode(rstat.rctime, p); | |
163 | ||
164 | ::decode(dirfragtree, p); | |
165 | ||
166 | ::decode(symlink, p); | |
167 | ||
168 | if (features & CEPH_FEATURE_DIRLAYOUTHASH) | |
169 | ::decode(dir_layout, p); | |
170 | else | |
171 | memset(&dir_layout, 0, sizeof(dir_layout)); | |
172 | ||
173 | ::decode(xattrbl, p); | |
174 | ||
175 | if (features & CEPH_FEATURE_MDS_INLINE_DATA) { | |
176 | ::decode(inline_version, p); | |
177 | ::decode(inline_data, p); | |
178 | } else { | |
179 | inline_version = CEPH_INLINE_NONE; | |
180 | } | |
181 | ||
182 | if (features & CEPH_FEATURE_MDS_QUOTA) | |
183 | ::decode(quota, p); | |
184 | else | |
185 | memset("a, 0, sizeof(quota)); | |
186 | ||
187 | if ((features & CEPH_FEATURE_FS_FILE_LAYOUT_V2)) | |
188 | ::decode(layout.pool_ns, p); | |
189 | if ((features & CEPH_FEATURE_FS_BTIME)) { | |
190 | ::decode(btime, p); | |
191 | ::decode(change_attr, p); | |
192 | } else { | |
193 | btime = utime_t(); | |
194 | change_attr = 0; | |
195 | } | |
196 | } | |
197 | ||
198 | // see CInode::encode_inodestat for encoder. | |
199 | }; | |
200 | ||
201 | ||
202 | class MClientReply : public Message { | |
203 | // reply data | |
204 | public: | |
205 | struct ceph_mds_reply_head head; | |
206 | bufferlist trace_bl; | |
207 | bufferlist extra_bl; | |
208 | bufferlist snapbl; | |
209 | ||
210 | public: | |
211 | int get_op() const { return head.op; } | |
212 | ||
213 | void set_mdsmap_epoch(epoch_t e) { head.mdsmap_epoch = e; } | |
214 | epoch_t get_mdsmap_epoch() const { return head.mdsmap_epoch; } | |
215 | ||
216 | int get_result() const { | |
217 | return ceph_to_host_errno((__s32)(__u32)head.result); | |
218 | } | |
219 | ||
220 | void set_result(int r) { head.result = r; } | |
221 | ||
222 | void set_unsafe() { head.safe = 0; } | |
223 | ||
224 | bool is_safe() const { return head.safe; } | |
225 | ||
226 | MClientReply() : Message(CEPH_MSG_CLIENT_REPLY) {} | |
227 | MClientReply(MClientRequest *req, int result = 0) : | |
228 | Message(CEPH_MSG_CLIENT_REPLY) { | |
229 | memset(&head, 0, sizeof(head)); | |
230 | header.tid = req->get_tid(); | |
231 | head.op = req->get_op(); | |
232 | head.result = result; | |
233 | head.safe = 1; | |
234 | } | |
235 | private: | |
236 | ~MClientReply() override {} | |
237 | ||
238 | public: | |
239 | const char *get_type_name() const override { return "creply"; } | |
240 | void print(ostream& o) const override { | |
241 | o << "client_reply(???:" << get_tid(); | |
242 | o << " = " << get_result(); | |
243 | if (get_result() <= 0) { | |
244 | o << " " << cpp_strerror(get_result()); | |
245 | } | |
246 | if (head.op & CEPH_MDS_OP_WRITE) { | |
247 | if (head.safe) | |
248 | o << " safe"; | |
249 | else | |
250 | o << " unsafe"; | |
251 | } | |
252 | o << ")"; | |
253 | } | |
254 | ||
255 | // serialization | |
256 | void decode_payload() override { | |
257 | bufferlist::iterator p = payload.begin(); | |
258 | ::decode(head, p); | |
259 | ::decode(trace_bl, p); | |
260 | ::decode(extra_bl, p); | |
261 | ::decode(snapbl, p); | |
262 | assert(p.end()); | |
263 | } | |
264 | void encode_payload(uint64_t features) override { | |
265 | ::encode(head, payload); | |
266 | ::encode(trace_bl, payload); | |
267 | ::encode(extra_bl, payload); | |
268 | ::encode(snapbl, payload); | |
269 | } | |
270 | ||
271 | ||
272 | // dir contents | |
273 | void set_extra_bl(bufferlist& bl) { | |
274 | extra_bl.claim(bl); | |
275 | } | |
276 | bufferlist &get_extra_bl() { | |
277 | return extra_bl; | |
278 | } | |
279 | ||
280 | // trace | |
281 | void set_trace(bufferlist& bl) { | |
282 | trace_bl.claim(bl); | |
283 | } | |
284 | bufferlist& get_trace_bl() { | |
285 | return trace_bl; | |
286 | } | |
287 | }; | |
288 | ||
289 | #endif |