]> git.proxmox.com Git - ceph.git/blame - ceph/src/messages/MClientReply.h
import quincy beta 17.1.0
[ceph.git] / ceph / src / messages / MClientReply.h
CommitLineData
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"
f67539c2 21#include "include/mempool.h"
7c673cae
FG
22#include "MClientRequest.h"
23
24#include "msg/Message.h"
25#include "include/ceph_features.h"
26#include "common/errno.h"
f67539c2 27#include "common/strescape.h"
7c673cae
FG
28
29/***
30 *
31 * MClientReply - container message for MDS reply to a client's MClientRequest
32 *
33 * key fields:
34 * long tid - transaction id, so the client can match up with pending request
35 * int result - error code, or fh if it was open
36 *
37 * for most requests:
38 * trace is a vector of InodeStat's tracing from root to the file/dir/whatever
39 * the operation referred to, so that the client can update it's info about what
40 * metadata lives on what MDS.
41 *
42 * for readdir replies:
43 * dir_contents is a vector of InodeStat*'s.
44 *
45 * that's mostly it, i think!
46 *
47 */
48
49
50struct LeaseStat {
51 // this matches ceph_mds_reply_lease
f67539c2
TL
52 __u16 mask = 0;
53 __u32 duration_ms = 0;
54 __u32 seq = 0;
55 std::string alternate_name;
7c673cae 56
f67539c2 57 LeaseStat() = default;
11fdf7f2
TL
58 LeaseStat(__u16 msk, __u32 dur, __u32 sq) : mask{msk}, duration_ms{dur}, seq{sq} {}
59
f67539c2 60 void decode(ceph::buffer::list::const_iterator &bl, const uint64_t features) {
11fdf7f2
TL
61 using ceph::decode;
62 if (features == (uint64_t)-1) {
f67539c2 63 DECODE_START(2, bl);
11fdf7f2
TL
64 decode(mask, bl);
65 decode(duration_ms, bl);
66 decode(seq, bl);
f67539c2
TL
67 if (struct_v >= 2)
68 decode(alternate_name, bl);
11fdf7f2
TL
69 DECODE_FINISH(bl);
70 }
71 else {
72 decode(mask, bl);
73 decode(duration_ms, bl);
74 decode(seq, bl);
75 }
7c673cae
FG
76 }
77};
7c673cae 78
f67539c2
TL
79inline std::ostream& operator<<(std::ostream& out, const LeaseStat& l) {
80 out << "lease(mask " << l.mask << " dur " << l.duration_ms;
81 if (l.alternate_name.size()) {
82 out << " altn " << binstrprint(l.alternate_name, 128) << ")";
83 }
84 return out << ")";
7c673cae
FG
85}
86
87struct DirStat {
88 // mds distribution hints
89 frag_t frag;
90 __s32 auth;
f67539c2 91 std::set<__s32> dist;
7c673cae
FG
92
93 DirStat() : auth(CDIR_AUTH_PARENT) {}
f67539c2 94 DirStat(ceph::buffer::list::const_iterator& p, const uint64_t features) {
11fdf7f2 95 decode(p, features);
7c673cae
FG
96 }
97
f67539c2 98 void decode(ceph::buffer::list::const_iterator& p, const uint64_t features) {
11fdf7f2
TL
99 using ceph::decode;
100 if (features == (uint64_t)-1) {
101 DECODE_START(1, p);
102 decode(frag, p);
103 decode(auth, p);
104 decode(dist, p);
105 DECODE_FINISH(p);
106 }
107 else {
108 decode(frag, p);
109 decode(auth, p);
110 decode(dist, p);
111 }
7c673cae
FG
112 }
113
114 // see CDir::encode_dirstat for encoder.
115};
116
117struct InodeStat {
118 vinodeno_t vino;
11fdf7f2
TL
119 uint32_t rdev = 0;
120 version_t version = 0;
121 version_t xattr_version = 0;
7c673cae
FG
122 ceph_mds_reply_cap cap;
123 file_layout_t layout;
81eedcae 124 utime_t ctime, btime, mtime, atime, snap_btime;
11fdf7f2
TL
125 uint32_t time_warp_seq = 0;
126 uint64_t size = 0, max_size = 0;
127 uint64_t change_attr = 0;
128 uint64_t truncate_size = 0;
129 uint32_t truncate_seq = 0;
130 uint32_t mode = 0, uid = 0, gid = 0, nlink = 0;
7c673cae
FG
131 frag_info_t dirstat;
132 nest_info_t rstat;
133
134 fragtree_t dirfragtree;
f67539c2 135 std::string symlink; // symlink content (if symlink)
7c673cae
FG
136
137 ceph_dir_layout dir_layout;
138
f67539c2 139 ceph::buffer::list xattrbl;
7c673cae 140
f67539c2 141 ceph::buffer::list inline_data;
7c673cae
FG
142 version_t inline_version;
143
144 quota_info_t quota;
145
11fdf7f2 146 mds_rank_t dir_pin;
f67539c2
TL
147 std::map<std::string,std::string> snap_metadata;
148
149 bool fscrypt = false; // fscrypt enabled ?
11fdf7f2 150
7c673cae
FG
151 public:
152 InodeStat() {}
f67539c2 153 InodeStat(ceph::buffer::list::const_iterator& p, const uint64_t features) {
7c673cae
FG
154 decode(p, features);
155 }
156
f67539c2 157 void decode(ceph::buffer::list::const_iterator &p, const uint64_t features) {
11fdf7f2
TL
158 using ceph::decode;
159 if (features == (uint64_t)-1) {
f67539c2 160 DECODE_START(6, p);
11fdf7f2
TL
161 decode(vino.ino, p);
162 decode(vino.snapid, p);
163 decode(rdev, p);
164 decode(version, p);
165 decode(xattr_version, p);
166 decode(cap, p);
167 {
168 ceph_file_layout legacy_layout;
169 decode(legacy_layout, p);
170 layout.from_legacy(legacy_layout);
171 }
172 decode(ctime, p);
173 decode(mtime, p);
174 decode(atime, p);
175 decode(time_warp_seq, p);
176 decode(size, p);
177 decode(max_size, p);
178 decode(truncate_size, p);
179 decode(truncate_seq, p);
180 decode(mode, p);
181 decode(uid, p);
182 decode(gid, p);
183 decode(nlink, p);
184 decode(dirstat.nfiles, p);
185 decode(dirstat.nsubdirs, p);
186 decode(rstat.rbytes, p);
187 decode(rstat.rfiles, p);
188 decode(rstat.rsubdirs, p);
189 decode(rstat.rctime, p);
190 decode(dirfragtree, p);
191 decode(symlink, p);
192 decode(dir_layout, p);
193 decode(xattrbl, p);
194 decode(inline_version, p);
195 decode(inline_data, p);
196 decode(quota, p);
197 decode(layout.pool_ns, p);
198 decode(btime, p);
199 decode(change_attr, p);
200 if (struct_v > 1) {
201 decode(dir_pin, p);
202 } else {
203 dir_pin = -ENODATA;
204 }
81eedcae
TL
205 if (struct_v >= 3) {
206 decode(snap_btime, p);
207 } // else remains zero
f67539c2
TL
208 if (struct_v >= 4) {
209 decode(rstat.rsnaps, p);
210 } // else remains zero
211 if (struct_v >= 5) {
212 decode(snap_metadata, p);
213 }
214 if (struct_v >= 6) {
215 decode(fscrypt, p);
216 }
11fdf7f2 217 DECODE_FINISH(p);
7c673cae 218 }
11fdf7f2
TL
219 else {
220 decode(vino.ino, p);
221 decode(vino.snapid, p);
222 decode(rdev, p);
223 decode(version, p);
224 decode(xattr_version, p);
225 decode(cap, p);
226 {
227 ceph_file_layout legacy_layout;
228 decode(legacy_layout, p);
229 layout.from_legacy(legacy_layout);
230 }
231 decode(ctime, p);
232 decode(mtime, p);
233 decode(atime, p);
234 decode(time_warp_seq, p);
235 decode(size, p);
236 decode(max_size, p);
237 decode(truncate_size, p);
238 decode(truncate_seq, p);
239 decode(mode, p);
240 decode(uid, p);
241 decode(gid, p);
242 decode(nlink, p);
243 decode(dirstat.nfiles, p);
244 decode(dirstat.nsubdirs, p);
245 decode(rstat.rbytes, p);
246 decode(rstat.rfiles, p);
247 decode(rstat.rsubdirs, p);
248 decode(rstat.rctime, p);
249 decode(dirfragtree, p);
250 decode(symlink, p);
251 if (features & CEPH_FEATURE_DIRLAYOUTHASH)
252 decode(dir_layout, p);
253 else
254 memset(&dir_layout, 0, sizeof(dir_layout));
7c673cae 255
11fdf7f2
TL
256 decode(xattrbl, p);
257
258 if (features & CEPH_FEATURE_MDS_INLINE_DATA) {
259 decode(inline_version, p);
260 decode(inline_data, p);
261 } else {
262 inline_version = CEPH_INLINE_NONE;
263 }
264
265 if (features & CEPH_FEATURE_MDS_QUOTA)
266 decode(quota, p);
267 else
268 quota = quota_info_t{};
269
270 if ((features & CEPH_FEATURE_FS_FILE_LAYOUT_V2))
271 decode(layout.pool_ns, p);
272
273 if ((features & CEPH_FEATURE_FS_BTIME)) {
274 decode(btime, p);
275 decode(change_attr, p);
276 } else {
277 btime = utime_t();
278 change_attr = 0;
279 }
7c673cae
FG
280 }
281 }
282
283 // see CInode::encode_inodestat for encoder.
284};
285
9f95a23c
TL
286struct openc_response_t {
287 _inodeno_t created_ino;
288 interval_set<inodeno_t> delegated_inos;
7c673cae 289
7c673cae 290public:
9f95a23c
TL
291 void encode(ceph::buffer::list& bl) const {
292 using ceph::encode;
293 ENCODE_START(1, 1, bl);
294 encode(created_ino, bl);
295 encode(delegated_inos, bl);
296 ENCODE_FINISH(bl);
297 }
f67539c2 298 void decode(ceph::buffer::list::const_iterator &p) {
9f95a23c
TL
299 using ceph::decode;
300 DECODE_START(1, p);
301 decode(created_ino, p);
302 decode(delegated_inos, p);
303 DECODE_FINISH(p);
304 }
305} __attribute__ ((__may_alias__));
306WRITE_CLASS_ENCODER(openc_response_t)
11fdf7f2 307
f67539c2 308class MClientReply final : public SafeMessage {
9f95a23c 309public:
11fdf7f2
TL
310 // reply data
311 struct ceph_mds_reply_head head {};
f67539c2
TL
312 ceph::buffer::list trace_bl;
313 ceph::buffer::list extra_bl;
314 ceph::buffer::list snapbl;
7c673cae 315
7c673cae
FG
316 int get_op() const { return head.op; }
317
318 void set_mdsmap_epoch(epoch_t e) { head.mdsmap_epoch = e; }
319 epoch_t get_mdsmap_epoch() const { return head.mdsmap_epoch; }
320
321 int get_result() const {
31f18b77 322 return ceph_to_hostos_errno((__s32)(__u32)head.result);
7c673cae
FG
323 }
324
325 void set_result(int r) { head.result = r; }
326
327 void set_unsafe() { head.safe = 0; }
328
329 bool is_safe() const { return head.safe; }
330
11fdf7f2 331protected:
9f95a23c 332 MClientReply() : SafeMessage{CEPH_MSG_CLIENT_REPLY} {}
11fdf7f2 333 MClientReply(const MClientRequest &req, int result = 0) :
9f95a23c 334 SafeMessage{CEPH_MSG_CLIENT_REPLY} {
7c673cae 335 memset(&head, 0, sizeof(head));
11fdf7f2
TL
336 header.tid = req.get_tid();
337 head.op = req.get_op();
7c673cae
FG
338 head.result = result;
339 head.safe = 1;
340 }
f67539c2 341 ~MClientReply() final {}
7c673cae
FG
342
343public:
11fdf7f2 344 std::string_view get_type_name() const override { return "creply"; }
f67539c2 345 void print(std::ostream& o) const override {
7c673cae
FG
346 o << "client_reply(???:" << get_tid();
347 o << " = " << get_result();
348 if (get_result() <= 0) {
349 o << " " << cpp_strerror(get_result());
350 }
351 if (head.op & CEPH_MDS_OP_WRITE) {
352 if (head.safe)
353 o << " safe";
354 else
355 o << " unsafe";
356 }
357 o << ")";
358 }
359
360 // serialization
361 void decode_payload() override {
f67539c2 362 using ceph::decode;
11fdf7f2
TL
363 auto p = payload.cbegin();
364 decode(head, p);
365 decode(trace_bl, p);
366 decode(extra_bl, p);
367 decode(snapbl, p);
368 ceph_assert(p.end());
7c673cae
FG
369 }
370 void encode_payload(uint64_t features) override {
11fdf7f2
TL
371 using ceph::encode;
372 encode(head, payload);
373 encode(trace_bl, payload);
374 encode(extra_bl, payload);
375 encode(snapbl, payload);
7c673cae
FG
376 }
377
378
379 // dir contents
f67539c2
TL
380 void set_extra_bl(ceph::buffer::list& bl) {
381 extra_bl = std::move(bl);
7c673cae 382 }
f67539c2 383 ceph::buffer::list& get_extra_bl() {
11fdf7f2
TL
384 return extra_bl;
385 }
f67539c2 386 const ceph::buffer::list& get_extra_bl() const {
7c673cae
FG
387 return extra_bl;
388 }
389
390 // trace
f67539c2
TL
391 void set_trace(ceph::buffer::list& bl) {
392 trace_bl = std::move(bl);
7c673cae 393 }
f67539c2 394 ceph::buffer::list& get_trace_bl() {
7c673cae
FG
395 return trace_bl;
396 }
f67539c2 397 const ceph::buffer::list& get_trace_bl() const {
11fdf7f2
TL
398 return trace_bl;
399 }
9f95a23c
TL
400private:
401 template<class T, typename... Args>
402 friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
20effc67
TL
403 template<class T, typename... Args>
404 friend MURef<T> crimson::make_message(Args&&... args);
7c673cae
FG
405};
406
407#endif