]> git.proxmox.com Git - ceph.git/blob - ceph/src/messages/MClientCaps.h
update sources to v12.1.0
[ceph.git] / ceph / src / messages / MClientCaps.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 #ifndef CEPH_MCLIENTCAPS_H
16 #define CEPH_MCLIENTCAPS_H
17
18 #include "msg/Message.h"
19 #include "include/ceph_features.h"
20
21 #define CLIENT_CAPS_SYNC (0x1)
22
23 class MClientCaps : public Message {
24 static const int HEAD_VERSION = 10;
25 static const int COMPAT_VERSION = 1;
26
27 public:
28 struct ceph_mds_caps_head head;
29
30 uint64_t size, max_size, truncate_size, change_attr;
31 uint32_t truncate_seq;
32 utime_t mtime, atime, ctime, btime;
33 uint32_t time_warp_seq;
34
35 struct ceph_mds_cap_peer peer;
36
37 bufferlist snapbl;
38 bufferlist xattrbl;
39 bufferlist flockbl;
40 version_t inline_version;
41 bufferlist inline_data;
42
43 // Receivers may not use their new caps until they have this OSD map
44 epoch_t osd_epoch_barrier;
45 ceph_tid_t oldest_flush_tid;
46 uint32_t caller_uid;
47 uint32_t caller_gid;
48
49 /* advisory CLIENT_CAPS_* flags to send to mds */
50 unsigned flags;
51
52 int get_caps() { return head.caps; }
53 int get_wanted() { return head.wanted; }
54 int get_dirty() { return head.dirty; }
55 ceph_seq_t get_seq() { return head.seq; }
56 ceph_seq_t get_issue_seq() { return head.issue_seq; }
57 ceph_seq_t get_mseq() { return head.migrate_seq; }
58
59 inodeno_t get_ino() { return inodeno_t(head.ino); }
60 inodeno_t get_realm() { return inodeno_t(head.realm); }
61 uint64_t get_cap_id() { return head.cap_id; }
62
63 uint64_t get_size() { return size; }
64 uint64_t get_max_size() { return max_size; }
65 __u32 get_truncate_seq() { return truncate_seq; }
66 uint64_t get_truncate_size() { return truncate_size; }
67 utime_t get_ctime() { return ctime; }
68 utime_t get_btime() { return btime; }
69 utime_t get_mtime() { return mtime; }
70 utime_t get_atime() { return atime; }
71 __u64 get_change_attr() { return change_attr; }
72 __u32 get_time_warp_seq() { return time_warp_seq; }
73
74 const file_layout_t& get_layout() {
75 return layout;
76 }
77
78 void set_layout(const file_layout_t &l) {
79 layout = l;
80 }
81
82 int get_migrate_seq() { return head.migrate_seq; }
83 int get_op() { return head.op; }
84
85 uint64_t get_client_tid() { return get_tid(); }
86 void set_client_tid(uint64_t s) { set_tid(s); }
87
88 snapid_t get_snap_follows() { return snapid_t(head.snap_follows); }
89 void set_snap_follows(snapid_t s) { head.snap_follows = s; }
90
91 void set_caps(int c) { head.caps = c; }
92 void set_wanted(int w) { head.wanted = w; }
93
94 void set_max_size(uint64_t ms) { max_size = ms; }
95
96 void set_migrate_seq(unsigned m) { head.migrate_seq = m; }
97 void set_op(int o) { head.op = o; }
98
99 void set_size(loff_t s) { size = s; }
100 void set_mtime(const utime_t &t) { mtime = t; }
101 void set_ctime(const utime_t &t) { ctime = t; }
102 void set_atime(const utime_t &t) { atime = t; }
103
104 void set_cap_peer(uint64_t id, ceph_seq_t seq, ceph_seq_t mseq, int mds, int flags) {
105 peer.cap_id = id;
106 peer.seq = seq;
107 peer.mseq = mseq;
108 peer.mds = mds;
109 peer.flags = flags;
110 }
111
112 void set_oldest_flush_tid(ceph_tid_t tid) { oldest_flush_tid = tid; }
113 ceph_tid_t get_oldest_flush_tid() { return oldest_flush_tid; }
114
115 void clear_dirty() { head.dirty = 0; }
116
117 MClientCaps()
118 : Message(CEPH_MSG_CLIENT_CAPS, HEAD_VERSION, COMPAT_VERSION),
119 size(0),
120 max_size(0),
121 truncate_size(0),
122 change_attr(0),
123 truncate_seq(0),
124 time_warp_seq(0),
125 osd_epoch_barrier(0),
126 oldest_flush_tid(0),
127 caller_uid(0), caller_gid(0),
128 flags(0) {
129 inline_version = 0;
130 }
131 MClientCaps(int op,
132 inodeno_t ino,
133 inodeno_t realm,
134 uint64_t id,
135 long seq,
136 int caps,
137 int wanted,
138 int dirty,
139 int mseq,
140 epoch_t oeb)
141 : Message(CEPH_MSG_CLIENT_CAPS, HEAD_VERSION, COMPAT_VERSION),
142 size(0),
143 max_size(0),
144 truncate_size(0),
145 change_attr(0),
146 truncate_seq(0),
147 time_warp_seq(0),
148 osd_epoch_barrier(oeb),
149 oldest_flush_tid(0),
150 caller_uid(0), caller_gid(0),
151 flags(0) {
152 memset(&head, 0, sizeof(head));
153 head.op = op;
154 head.ino = ino;
155 head.realm = realm;
156 head.cap_id = id;
157 head.seq = seq;
158 head.caps = caps;
159 head.wanted = wanted;
160 head.dirty = dirty;
161 head.migrate_seq = mseq;
162 memset(&peer, 0, sizeof(peer));
163 inline_version = 0;
164 }
165 MClientCaps(int op,
166 inodeno_t ino, inodeno_t realm,
167 uint64_t id, int mseq, epoch_t oeb)
168 : Message(CEPH_MSG_CLIENT_CAPS, HEAD_VERSION, COMPAT_VERSION),
169 size(0),
170 max_size(0),
171 truncate_size(0),
172 change_attr(0),
173 truncate_seq(0),
174 time_warp_seq(0),
175 osd_epoch_barrier(oeb),
176 oldest_flush_tid(0),
177 caller_uid(0), caller_gid(0),
178 flags(0) {
179 memset(&head, 0, sizeof(head));
180 head.op = op;
181 head.ino = ino;
182 head.realm = realm;
183 head.cap_id = id;
184 head.migrate_seq = mseq;
185 memset(&peer, 0, sizeof(peer));
186 inline_version = 0;
187 }
188 private:
189 file_layout_t layout;
190
191 ~MClientCaps() override {}
192
193 public:
194 const char *get_type_name() const override { return "Cfcap";}
195 void print(ostream& out) const override {
196 out << "client_caps(" << ceph_cap_op_name(head.op)
197 << " ino " << inodeno_t(head.ino)
198 << " " << head.cap_id
199 << " seq " << head.seq;
200 if (get_tid())
201 out << " tid " << get_tid();
202 out << " caps=" << ccap_string(head.caps)
203 << " dirty=" << ccap_string(head.dirty)
204 << " wanted=" << ccap_string(head.wanted);
205 out << " follows " << snapid_t(head.snap_follows);
206 if (head.migrate_seq)
207 out << " mseq " << head.migrate_seq;
208
209 out << " size " << size << "/" << max_size;
210 if (truncate_seq)
211 out << " ts " << truncate_seq << "/" << truncate_size;
212 out << " mtime " << mtime;
213 if (time_warp_seq)
214 out << " tws " << time_warp_seq;
215
216 if (head.xattr_version)
217 out << " xattrs(v=" << head.xattr_version << " l=" << xattrbl.length() << ")";
218
219 out << ")";
220 }
221
222 void decode_payload() override {
223 bufferlist::iterator p = payload.begin();
224 ::decode(head, p);
225 ceph_mds_caps_body_legacy body;
226 ::decode(body, p);
227 if (head.op == CEPH_CAP_OP_EXPORT) {
228 peer = body.peer;
229 } else {
230 size = body.size;
231 max_size = body.max_size;
232 truncate_size = body.truncate_size;
233 truncate_seq = body.truncate_seq;
234 mtime = utime_t(body.mtime);
235 atime = utime_t(body.atime);
236 ctime = utime_t(body.ctime);
237 layout.from_legacy(body.layout);
238 time_warp_seq = body.time_warp_seq;
239 }
240 ::decode_nohead(head.snap_trace_len, snapbl, p);
241
242 assert(middle.length() == head.xattr_len);
243 if (head.xattr_len)
244 xattrbl = middle;
245
246 // conditionally decode flock metadata
247 if (header.version >= 2)
248 ::decode(flockbl, p);
249
250 if (header.version >= 3) {
251 if (head.op == CEPH_CAP_OP_IMPORT)
252 ::decode(peer, p);
253 }
254
255 if (header.version >= 4) {
256 ::decode(inline_version, p);
257 ::decode(inline_data, p);
258 } else {
259 inline_version = CEPH_INLINE_NONE;
260 }
261
262 if (header.version >= 5) {
263 ::decode(osd_epoch_barrier, p);
264 }
265 if (header.version >= 6) {
266 ::decode(oldest_flush_tid, p);
267 }
268 if (header.version >= 7) {
269 ::decode(caller_uid, p);
270 ::decode(caller_gid, p);
271 }
272 if (header.version >= 8) {
273 ::decode(layout.pool_ns, p);
274 }
275 if (header.version >= 9) {
276 ::decode(btime, p);
277 ::decode(change_attr, p);
278 }
279 if (header.version >= 10) {
280 ::decode(flags, p);
281 }
282 }
283 void encode_payload(uint64_t features) override {
284 header.version = HEAD_VERSION;
285 head.snap_trace_len = snapbl.length();
286 head.xattr_len = xattrbl.length();
287
288 ::encode(head, payload);
289 ceph_mds_caps_body_legacy body;
290 if (head.op == CEPH_CAP_OP_EXPORT) {
291 memset(&body, 0, sizeof(body));
292 body.peer = peer;
293 } else {
294 body.size = size;
295 body.max_size = max_size;
296 body.truncate_size = truncate_size;
297 body.truncate_seq = truncate_seq;
298 mtime.encode_timeval(&body.mtime);
299 atime.encode_timeval(&body.atime);
300 ctime.encode_timeval(&body.ctime);
301 layout.to_legacy(&body.layout);
302 body.time_warp_seq = time_warp_seq;
303 }
304 ::encode(body, payload);
305 ::encode_nohead(snapbl, payload);
306
307 middle = xattrbl;
308
309 // conditionally include flock metadata
310 if (features & CEPH_FEATURE_FLOCK) {
311 ::encode(flockbl, payload);
312 } else {
313 header.version = 1;
314 return;
315 }
316
317 if (features & CEPH_FEATURE_EXPORT_PEER) {
318 if (head.op == CEPH_CAP_OP_IMPORT)
319 ::encode(peer, payload);
320 } else {
321 header.version = 2;
322 return;
323 }
324
325 if (features & CEPH_FEATURE_MDS_INLINE_DATA) {
326 ::encode(inline_version, payload);
327 ::encode(inline_data, payload);
328 } else {
329 ::encode(inline_version, payload);
330 ::encode(bufferlist(), payload);
331 }
332
333 ::encode(osd_epoch_barrier, payload);
334 ::encode(oldest_flush_tid, payload);
335 ::encode(caller_uid, payload);
336 ::encode(caller_gid, payload);
337
338 ::encode(layout.pool_ns, payload);
339 ::encode(btime, payload);
340 ::encode(change_attr, payload);
341 ::encode(flags, payload);
342 }
343 };
344
345 #endif