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