]> git.proxmox.com Git - ceph.git/blame - ceph/src/messages/MClientRequest.h
Import ceph 15.2.8
[ceph.git] / ceph / src / messages / MClientRequest.h
CommitLineData
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
16#ifndef CEPH_MCLIENTREQUEST_H
17#define CEPH_MCLIENTREQUEST_H
18
19/**
20 *
21 * MClientRequest - container for a client METADATA request. created/sent by clients.
22 * can be forwarded around between MDS's.
23 *
24 * int client - the originating client
25 * long tid - transaction id, unique among requests for that client. probably just a counter!
26 * -> the MDS passes the Request to the Reply constructor, so this always matches.
27 *
28 * int op - the metadata op code. MDS_OP_RENAME, etc.
29 * int caller_uid, _gid - guess
30 *
31 * fixed size arguments are in a union.
32 * there's also a string argument, for e.g. symlink().
33 *
34 */
35
11fdf7f2 36#include <string_view>
94b18763 37
7c673cae
FG
38#include "msg/Message.h"
39#include "include/filepath.h"
40#include "mds/mdstypes.h"
41#include "include/ceph_features.h"
42
43#include <sys/types.h>
44#include <utime.h>
45#include <sys/stat.h>
46#include <fcntl.h>
47
48
49// metadata ops.
50
9f95a23c 51class MClientRequest : public SafeMessage {
11fdf7f2
TL
52private:
53 static constexpr int HEAD_VERSION = 4;
54 static constexpr int COMPAT_VERSION = 1;
7c673cae
FG
55
56public:
11fdf7f2 57 mutable struct ceph_mds_request_head head; /* XXX HACK! */
7c673cae
FG
58 utime_t stamp;
59
60 struct Release {
61 mutable ceph_mds_request_release item;
62 string dname;
63
64 Release() : item(), dname() {}
65 Release(const ceph_mds_request_release& rel, string name) :
66 item(rel), dname(name) {}
67
68 void encode(bufferlist& bl) const {
11fdf7f2 69 using ceph::encode;
7c673cae 70 item.dname_len = dname.length();
11fdf7f2
TL
71 encode(item, bl);
72 encode_nohead(dname, bl);
7c673cae 73 }
11fdf7f2
TL
74 void decode(bufferlist::const_iterator& bl) {
75 using ceph::decode;
76 decode(item, bl);
77 decode_nohead(item.dname_len, dname, bl);
7c673cae
FG
78 }
79 };
11fdf7f2 80 mutable vector<Release> releases; /* XXX HACK! */
7c673cae
FG
81
82 // path arguments
83 filepath path, path2;
84 vector<uint64_t> gid_list;
85
11fdf7f2
TL
86 /* XXX HACK */
87 mutable bool queued_for_replay = false;
7c673cae 88
11fdf7f2 89protected:
7c673cae
FG
90 // cons
91 MClientRequest()
9f95a23c 92 : SafeMessage(CEPH_MSG_CLIENT_REQUEST, HEAD_VERSION, COMPAT_VERSION) {}
7c673cae 93 MClientRequest(int op)
9f95a23c 94 : SafeMessage(CEPH_MSG_CLIENT_REQUEST, HEAD_VERSION, COMPAT_VERSION) {
7c673cae
FG
95 memset(&head, 0, sizeof(head));
96 head.op = op;
97 }
7c673cae
FG
98 ~MClientRequest() override {}
99
100public:
101 void set_mdsmap_epoch(epoch_t e) { head.mdsmap_epoch = e; }
11fdf7f2 102 epoch_t get_mdsmap_epoch() const { return head.mdsmap_epoch; }
7c673cae 103 epoch_t get_osdmap_epoch() const {
11fdf7f2 104 ceph_assert(head.op == CEPH_MDS_OP_SETXATTR);
7c673cae
FG
105 if (header.version >= 3)
106 return head.args.setxattr.osdmap_epoch;
107 else
108 return 0;
109 }
110 void set_osdmap_epoch(epoch_t e) {
11fdf7f2 111 ceph_assert(head.op == CEPH_MDS_OP_SETXATTR);
7c673cae
FG
112 head.args.setxattr.osdmap_epoch = e;
113 }
114
11fdf7f2 115 metareqid_t get_reqid() const {
7c673cae
FG
116 // FIXME: for now, assume clients always have 1 incarnation
117 return metareqid_t(get_orig_source(), header.tid);
118 }
119
120 /*bool open_file_mode_is_readonly() {
121 return file_mode_is_readonly(ceph_flags_to_mode(head.args.open.flags));
122 }*/
11fdf7f2 123 bool may_write() const {
7c673cae
FG
124 return
125 (head.op & CEPH_MDS_OP_WRITE) ||
126 (head.op == CEPH_MDS_OP_OPEN && (head.args.open.flags & (O_CREAT|O_TRUNC)));
127 }
128
129 int get_flags() const {
130 return head.flags;
131 }
11fdf7f2 132 bool is_replay() const {
7c673cae
FG
133 return get_flags() & CEPH_MDS_FLAG_REPLAY;
134 }
9f95a23c
TL
135 bool is_async() const {
136 return get_flags() & CEPH_MDS_FLAG_ASYNC;
137 }
7c673cae
FG
138
139 // normal fields
140 void set_stamp(utime_t t) { stamp = t; }
141 void set_oldest_client_tid(ceph_tid_t t) { head.oldest_client_tid = t; }
142 void inc_num_fwd() { head.num_fwd = head.num_fwd + 1; }
143 void set_retry_attempt(int a) { head.num_retry = a; }
144 void set_filepath(const filepath& fp) { path = fp; }
145 void set_filepath2(const filepath& fp) { path2 = fp; }
11fdf7f2 146 void set_string2(const char *s) { path2.set_path(std::string_view(s), 0); }
7c673cae
FG
147 void set_caller_uid(unsigned u) { head.caller_uid = u; }
148 void set_caller_gid(unsigned g) { head.caller_gid = g; }
149 void set_gid_list(int count, const gid_t *gids) {
150 gid_list.reserve(count);
151 for (int i = 0; i < count; ++i) {
152 gid_list.push_back(gids[i]);
153 }
154 }
155 void set_dentry_wanted() {
156 head.flags = head.flags | CEPH_MDS_FLAG_WANT_DENTRY;
157 }
158 void set_replayed_op() {
159 head.flags = head.flags | CEPH_MDS_FLAG_REPLAY;
160 }
9f95a23c
TL
161 void set_async_op() {
162 head.flags = head.flags | CEPH_MDS_FLAG_ASYNC;
163 }
7c673cae
FG
164
165 utime_t get_stamp() const { return stamp; }
166 ceph_tid_t get_oldest_client_tid() const { return head.oldest_client_tid; }
167 int get_num_fwd() const { return head.num_fwd; }
168 int get_retry_attempt() const { return head.num_retry; }
169 int get_op() const { return head.op; }
170 unsigned get_caller_uid() const { return head.caller_uid; }
171 unsigned get_caller_gid() const { return head.caller_gid; }
172 const vector<uint64_t>& get_caller_gid_list() const { return gid_list; }
173
174 const string& get_path() const { return path.get_path(); }
175 const filepath& get_filepath() const { return path; }
176 const string& get_path2() const { return path2.get_path(); }
177 const filepath& get_filepath2() const { return path2; }
178
11fdf7f2 179 int get_dentry_wanted() const { return get_flags() & CEPH_MDS_FLAG_WANT_DENTRY; }
7c673cae 180
11fdf7f2
TL
181 void mark_queued_for_replay() const { queued_for_replay = true; }
182 bool is_queued_for_replay() const { return queued_for_replay; }
7c673cae
FG
183
184 void decode_payload() override {
11fdf7f2 185 auto p = payload.cbegin();
7c673cae
FG
186
187 if (header.version >= 4) {
11fdf7f2 188 decode(head, p);
7c673cae
FG
189 } else {
190 struct ceph_mds_request_head_legacy old_mds_head;
191
11fdf7f2 192 decode(old_mds_head, p);
7c673cae
FG
193 copy_from_legacy_head(&head, &old_mds_head);
194 head.version = 0;
195
196 /* Can't set the btime from legacy struct */
197 if (head.op == CEPH_MDS_OP_SETATTR) {
198 int localmask = head.args.setattr.mask;
199
200 localmask &= ~CEPH_SETATTR_BTIME;
201
9f95a23c 202 head.args.setattr.btime = { init_le32(0), init_le32(0) };
7c673cae
FG
203 head.args.setattr.mask = localmask;
204 }
205 }
206
11fdf7f2
TL
207 decode(path, p);
208 decode(path2, p);
209 decode_nohead(head.num_releases, releases, p);
7c673cae 210 if (header.version >= 2)
11fdf7f2 211 decode(stamp, p);
7c673cae 212 if (header.version >= 4) // epoch 3 was for a ceph_mds_request_args change
11fdf7f2 213 decode(gid_list, p);
7c673cae
FG
214 }
215
216 void encode_payload(uint64_t features) override {
11fdf7f2 217 using ceph::encode;
7c673cae
FG
218 head.num_releases = releases.size();
219 head.version = CEPH_MDS_REQUEST_HEAD_VERSION;
220
221 if (features & CEPH_FEATURE_FS_BTIME) {
11fdf7f2 222 encode(head, payload);
7c673cae
FG
223 } else {
224 struct ceph_mds_request_head_legacy old_mds_head;
225
226 copy_to_legacy_head(&old_mds_head, &head);
11fdf7f2 227 encode(old_mds_head, payload);
7c673cae
FG
228 }
229
11fdf7f2
TL
230 encode(path, payload);
231 encode(path2, payload);
232 encode_nohead(releases, payload);
233 encode(stamp, payload);
234 encode(gid_list, payload);
7c673cae
FG
235 }
236
11fdf7f2 237 std::string_view get_type_name() const override { return "creq"; }
7c673cae
FG
238 void print(ostream& out) const override {
239 out << "client_request(" << get_orig_source()
240 << ":" << get_tid()
241 << " " << ceph_mds_op_name(get_op());
242 if (head.op == CEPH_MDS_OP_GETATTR)
243 out << " " << ccap_string(head.args.getattr.mask);
244 if (head.op == CEPH_MDS_OP_SETATTR) {
245 if (head.args.setattr.mask & CEPH_SETATTR_MODE)
246 out << " mode=0" << std::oct << head.args.setattr.mode << std::dec;
247 if (head.args.setattr.mask & CEPH_SETATTR_UID)
248 out << " uid=" << head.args.setattr.uid;
249 if (head.args.setattr.mask & CEPH_SETATTR_GID)
250 out << " gid=" << head.args.setattr.gid;
251 if (head.args.setattr.mask & CEPH_SETATTR_SIZE)
252 out << " size=" << head.args.setattr.size;
253 if (head.args.setattr.mask & CEPH_SETATTR_MTIME)
254 out << " mtime=" << utime_t(head.args.setattr.mtime);
255 if (head.args.setattr.mask & CEPH_SETATTR_ATIME)
256 out << " atime=" << utime_t(head.args.setattr.atime);
257 }
258 if (head.op == CEPH_MDS_OP_SETFILELOCK ||
259 head.op == CEPH_MDS_OP_GETFILELOCK) {
11fdf7f2 260 out << " rule " << (int)head.args.filelock_change.rule
7c673cae
FG
261 << ", type " << (int)head.args.filelock_change.type
262 << ", owner " << head.args.filelock_change.owner
263 << ", pid " << head.args.filelock_change.pid
264 << ", start " << head.args.filelock_change.start
265 << ", length " << head.args.filelock_change.length
266 << ", wait " << (int)head.args.filelock_change.wait;
267 }
268 //if (!get_filepath().empty())
269 out << " " << get_filepath();
270 if (!get_filepath2().empty())
271 out << " " << get_filepath2();
272 if (stamp != utime_t())
273 out << " " << stamp;
274 if (head.num_retry)
275 out << " RETRY=" << (int)head.num_retry;
9f95a23c
TL
276 if (is_async())
277 out << " ASYNC";
278 if (is_replay())
7c673cae
FG
279 out << " REPLAY";
280 if (queued_for_replay)
281 out << " QUEUED_FOR_REPLAY";
282 out << " caller_uid=" << head.caller_uid
283 << ", caller_gid=" << head.caller_gid
284 << '{';
285 for (auto i = gid_list.begin(); i != gid_list.end(); ++i)
286 out << *i << ',';
287 out << '}'
288 << ")";
289 }
9f95a23c
TL
290private:
291 template<class T, typename... Args>
292 friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
7c673cae
FG
293};
294
295WRITE_CLASS_ENCODER(MClientRequest::Release)
296
297#endif