]> git.proxmox.com Git - ceph.git/blob - ceph/src/messages/MClientReply.h
update sources to v12.1.0
[ceph.git] / ceph / src / messages / MClientReply.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-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(&quota, 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_hostos_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