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