1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
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.
16 #ifndef CEPH_MCLIENTREPLY_H
17 #define CEPH_MCLIENTREPLY_H
19 #include "include/types.h"
20 #include "include/fs_types.h"
21 #include "MClientRequest.h"
23 #include "msg/Message.h"
24 #include "include/ceph_features.h"
25 #include "common/errno.h"
29 * MClientReply - container message for MDS reply to a client's MClientRequest
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
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.
40 * for readdir replies:
41 * dir_contents is a vector of InodeStat*'s.
43 * that's mostly it, i think!
49 // this matches ceph_mds_reply_lease
54 LeaseStat() : mask(0), duration_ms(0), seq(0) {}
56 void encode(bufferlist
&bl
) const {
58 ::encode(duration_ms
, bl
);
61 void decode(bufferlist::iterator
&bl
) {
63 ::decode(duration_ms
, bl
);
67 WRITE_CLASS_ENCODER(LeaseStat
)
69 inline ostream
& operator<<(ostream
& out
, const LeaseStat
& l
) {
70 return out
<< "lease(mask " << l
.mask
<< " dur " << l
.duration_ms
<< ")";
74 // mds distribution hints
79 DirStat() : auth(CDIR_AUTH_PARENT
) {}
80 DirStat(bufferlist::iterator
& p
) {
84 void encode(bufferlist
& bl
) {
89 void decode(bufferlist::iterator
& p
) {
95 // see CDir::encode_dirstat for encoder.
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
;
115 fragtree_t dirfragtree
;
116 string symlink
; // symlink content (if symlink)
118 ceph_dir_layout dir_layout
;
122 bufferlist inline_data
;
123 version_t inline_version
;
129 InodeStat(bufferlist::iterator
& p
, uint64_t features
) {
133 void decode(bufferlist::iterator
&p
, uint64_t features
) {
134 ::decode(vino
.ino
, p
);
135 ::decode(vino
.snapid
, p
);
137 ::decode(version
, p
);
138 ::decode(xattr_version
, p
);
141 ceph_file_layout legacy_layout
;
142 ::decode(legacy_layout
, p
);
143 layout
.from_legacy(legacy_layout
);
148 ::decode(time_warp_seq
, p
);
150 ::decode(max_size
, p
);
151 ::decode(truncate_size
, p
);
152 ::decode(truncate_seq
, 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
);
164 ::decode(dirfragtree
, p
);
166 ::decode(symlink
, p
);
168 if (features
& CEPH_FEATURE_DIRLAYOUTHASH
)
169 ::decode(dir_layout
, p
);
171 memset(&dir_layout
, 0, sizeof(dir_layout
));
173 ::decode(xattrbl
, p
);
175 if (features
& CEPH_FEATURE_MDS_INLINE_DATA
) {
176 ::decode(inline_version
, p
);
177 ::decode(inline_data
, p
);
179 inline_version
= CEPH_INLINE_NONE
;
182 if (features
& CEPH_FEATURE_MDS_QUOTA
)
185 memset("a
, 0, sizeof(quota
));
187 if ((features
& CEPH_FEATURE_FS_FILE_LAYOUT_V2
))
188 ::decode(layout
.pool_ns
, p
);
189 if ((features
& CEPH_FEATURE_FS_BTIME
)) {
191 ::decode(change_attr
, p
);
198 // see CInode::encode_inodestat for encoder.
202 class MClientReply
: public Message
{
205 struct ceph_mds_reply_head head
;
211 int get_op() const { return head
.op
; }
213 void set_mdsmap_epoch(epoch_t e
) { head
.mdsmap_epoch
= e
; }
214 epoch_t
get_mdsmap_epoch() const { return head
.mdsmap_epoch
; }
216 int get_result() const {
217 return ceph_to_hostos_errno((__s32
)(__u32
)head
.result
);
220 void set_result(int r
) { head
.result
= r
; }
222 void set_unsafe() { head
.safe
= 0; }
224 bool is_safe() const { return head
.safe
; }
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
;
236 ~MClientReply() override
{}
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());
246 if (head
.op
& CEPH_MDS_OP_WRITE
) {
256 void decode_payload() override
{
257 bufferlist::iterator p
= payload
.begin();
259 ::decode(trace_bl
, p
);
260 ::decode(extra_bl
, p
);
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
);
273 void set_extra_bl(bufferlist
& bl
) {
276 bufferlist
&get_extra_bl() {
281 void set_trace(bufferlist
& bl
) {
284 bufferlist
& get_trace_bl() {