Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / 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