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