]> git.proxmox.com Git - ceph.git/blame - ceph/src/client/MetaRequest.h
update sources to 12.2.7
[ceph.git] / ceph / src / client / MetaRequest.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#ifndef CEPH_CLIENT_METAREQUEST_H
5#define CEPH_CLIENT_METAREQUEST_H
6
7
8#include "include/types.h"
9#include "include/xlist.h"
10#include "include/filepath.h"
7c673cae
FG
11#include "mds/mdstypes.h"
12#include "InodeRef.h"
13#include "UserPerm.h"
14
15#include "messages/MClientRequest.h"
16
17class MClientReply;
18class Dentry;
19class dir_result_t;
20
21struct MetaRequest {
22private:
23 InodeRef _inode, _old_inode, _other_inode;
24 Dentry *_dentry; //associated with path
25 Dentry *_old_dentry; //associated with path2
26 int abort_rc;
27public:
28 uint64_t tid;
29 utime_t op_stamp;
30 ceph_mds_request_head head;
31 filepath path, path2;
32 bufferlist data;
33 int inode_drop; //the inode caps this operation will drop
34 int inode_unless; //unless we have these caps already
35 int old_inode_drop, old_inode_unless;
36 int dentry_drop, dentry_unless;
37 int old_dentry_drop, old_dentry_unless;
38 int other_inode_drop, other_inode_unless;
39 vector<MClientRequest::Release> cap_releases;
40
41 int regetattr_mask; // getattr mask if i need to re-stat after a traceless reply
42
43 utime_t sent_stamp;
44 mds_rank_t mds; // who i am asking
45 mds_rank_t resend_mds; // someone wants you to (re)send the request here
46 bool send_to_auth; // must send to auth mds
47 __u32 sent_on_mseq; // mseq at last submission of this request
48 int num_fwd; // # of times i've been forwarded
49 int retry_attempt;
31f18b77 50 std::atomic<uint64_t> ref = { 1 };
7c673cae
FG
51
52 MClientReply *reply; // the reply
53 bool kick;
54 bool success;
55
56 // readdir result
57 dir_result_t *dirp;
58
59 //possible responses
60 bool got_unsafe;
61
62 xlist<MetaRequest*>::item item;
63 xlist<MetaRequest*>::item unsafe_item;
64 xlist<MetaRequest*>::item unsafe_dir_item;
65 xlist<MetaRequest*>::item unsafe_target_item;
66
67 Cond *caller_cond; // who to take up
68 Cond *dispatch_cond; // who to kick back
69 list<Cond*> waitfor_safe;
70
71 InodeRef target;
72 UserPerm perms;
73
74 explicit MetaRequest(int op) :
75 _dentry(NULL), _old_dentry(NULL), abort_rc(0),
76 tid(0),
77 inode_drop(0), inode_unless(0),
78 old_inode_drop(0), old_inode_unless(0),
79 dentry_drop(0), dentry_unless(0),
80 old_dentry_drop(0), old_dentry_unless(0),
81 other_inode_drop(0), other_inode_unless(0),
82 regetattr_mask(0),
83 mds(-1), resend_mds(-1), send_to_auth(false), sent_on_mseq(0),
84 num_fwd(0), retry_attempt(0),
31f18b77 85 reply(0),
7c673cae
FG
86 kick(false), success(false),
87 got_unsafe(false), item(this), unsafe_item(this),
88 unsafe_dir_item(this), unsafe_target_item(this),
89 caller_cond(0), dispatch_cond(0) {
90 memset(&head, 0, sizeof(head));
91 head.op = op;
92 }
93 ~MetaRequest();
94
95 /**
96 * Prematurely terminate the request, such that callers
97 * to make_request will receive `rc` as their result.
98 */
99 void abort(int rc)
100 {
101 assert(rc != 0);
102 abort_rc = rc;
103 }
104
105 /**
106 * Whether abort() has been called for this request
107 */
108 inline bool aborted() const
109 {
110 return abort_rc != 0;
111 }
112
113 /**
114 * Given that abort() has been called for this request, what `rc` was
115 * passed into it?
116 */
117 int get_abort_code() const
118 {
119 return abort_rc;
120 }
121
122 void set_inode(Inode *in) {
123 _inode = in;
124 }
125 Inode *inode() {
126 return _inode.get();
127 }
128 void take_inode(InodeRef *out) {
129 out->swap(_inode);
130 }
131 void set_old_inode(Inode *in) {
132 _old_inode = in;
133 }
134 Inode *old_inode() {
135 return _old_inode.get();
136 }
137 void take_old_inode(InodeRef *out) {
138 out->swap(_old_inode);
139 }
140 void set_other_inode(Inode *in) {
141 _other_inode = in;
142 }
143 Inode *other_inode() {
144 return _other_inode.get();
145 }
146 void take_other_inode(InodeRef *out) {
147 out->swap(_other_inode);
148 }
149 void set_dentry(Dentry *d);
150 Dentry *dentry();
151 void set_old_dentry(Dentry *d);
152 Dentry *old_dentry();
153
154 MetaRequest* get() {
31f18b77 155 ref++;
7c673cae
FG
156 return this;
157 }
158
159 /// psuedo-private put method; use Client::put_request()
160 bool _put() {
31f18b77 161 int v = --ref;
7c673cae
FG
162 return v == 0;
163 }
164
165 // normal fields
166 void set_tid(ceph_tid_t t) { tid = t; }
167 void set_oldest_client_tid(ceph_tid_t t) { head.oldest_client_tid = t; }
168 void inc_num_fwd() { head.num_fwd = head.num_fwd + 1; }
169 void set_retry_attempt(int a) { head.num_retry = a; }
170 void set_filepath(const filepath& fp) { path = fp; }
171 void set_filepath2(const filepath& fp) { path2 = fp; }
94b18763 172 void set_string2(const char *s) { path2.set_path(boost::string_view(s), 0); }
7c673cae
FG
173 void set_caller_perms(const UserPerm& _perms) {
174 perms.shallow_copy(_perms);
175 head.caller_uid = perms.uid();
176 head.caller_gid = perms.gid();
177 }
178 uid_t get_uid() { return perms.uid(); }
179 uid_t get_gid() { return perms.gid(); }
180 void set_data(const bufferlist &d) { data = d; }
181 void set_dentry_wanted() {
182 head.flags = head.flags | CEPH_MDS_FLAG_WANT_DENTRY;
183 }
184 int get_op() { return head.op; }
185 ceph_tid_t get_tid() { return tid; }
186 filepath& get_filepath() { return path; }
187 filepath& get_filepath2() { return path2; }
188
189 bool is_write() {
190 return
191 (head.op & CEPH_MDS_OP_WRITE) ||
192 (head.op == CEPH_MDS_OP_OPEN && (head.args.open.flags & (O_CREAT|O_TRUNC)));
193 }
194 bool can_forward() {
195 if ((head.op & CEPH_MDS_OP_WRITE) ||
196 head.op == CEPH_MDS_OP_OPEN) // do not forward _any_ open request.
197 return false;
198 return true;
199 }
200 bool auth_is_best() {
201 if ((head.op & CEPH_MDS_OP_WRITE) || head.op == CEPH_MDS_OP_OPEN ||
28e407b8 202 head.op == CEPH_MDS_OP_READDIR || send_to_auth)
7c673cae
FG
203 return true;
204 return false;
205 }
206
207 void dump(Formatter *f) const;
208
209};
210
211#endif