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() {