]>
Commit | Line | Data |
---|---|---|
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" | |
11fdf7f2 | 16 | #include "messages/MClientReply.h" |
7c673cae | 17 | |
7c673cae FG |
18 | class Dentry; |
19 | class dir_result_t; | |
20 | ||
21 | struct MetaRequest { | |
22 | private: | |
23 | InodeRef _inode, _old_inode, _other_inode; | |
24 | Dentry *_dentry; //associated with path | |
25 | Dentry *_old_dentry; //associated with path2 | |
26 | int abort_rc; | |
27 | public: | |
28 | uint64_t tid; | |
29 | utime_t op_stamp; | |
30 | ceph_mds_request_head head; | |
31 | filepath path, path2; | |
f67539c2 | 32 | std::string alternate_name; |
7c673cae FG |
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; | |
31f18b77 | 51 | std::atomic<uint64_t> ref = { 1 }; |
7c673cae | 52 | |
9f95a23c | 53 | ceph::cref_t<MClientReply> reply; // the reply |
7c673cae FG |
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 | ||
9f95a23c TL |
68 | ceph::condition_variable *caller_cond; // who to take up |
69 | ceph::condition_variable *dispatch_cond; // who to kick back | |
70 | list<ceph::condition_variable*> waitfor_safe; | |
7c673cae FG |
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), | |
11fdf7f2 TL |
86 | reply(0), |
87 | kick(false), success(false), dirp(NULL), | |
7c673cae FG |
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 | { | |
11fdf7f2 | 102 | ceph_assert(rc != 0); |
7c673cae FG |
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() { | |
31f18b77 | 156 | ref++; |
7c673cae FG |
157 | return this; |
158 | } | |
159 | ||
160 | /// psuedo-private put method; use Client::put_request() | |
161 | bool _put() { | |
31f18b77 | 162 | int v = --ref; |
7c673cae FG |
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; } | |
f67539c2 | 173 | void set_alternate_name(std::string an) { alternate_name = an; } |
11fdf7f2 | 174 | void set_string2(const char *s) { path2.set_path(std::string_view(s), 0); } |
7c673cae FG |
175 | void set_caller_perms(const UserPerm& _perms) { |
176 | perms.shallow_copy(_perms); | |
177 | head.caller_uid = perms.uid(); | |
178 | head.caller_gid = perms.gid(); | |
179 | } | |
180 | uid_t get_uid() { return perms.uid(); } | |
181 | uid_t get_gid() { return perms.gid(); } | |
182 | void set_data(const bufferlist &d) { data = d; } | |
183 | void set_dentry_wanted() { | |
184 | head.flags = head.flags | CEPH_MDS_FLAG_WANT_DENTRY; | |
185 | } | |
186 | int get_op() { return head.op; } | |
187 | ceph_tid_t get_tid() { return tid; } | |
188 | filepath& get_filepath() { return path; } | |
189 | filepath& get_filepath2() { return path2; } | |
190 | ||
191 | bool is_write() { | |
192 | return | |
193 | (head.op & CEPH_MDS_OP_WRITE) || | |
194 | (head.op == CEPH_MDS_OP_OPEN && (head.args.open.flags & (O_CREAT|O_TRUNC))); | |
195 | } | |
196 | bool can_forward() { | |
197 | if ((head.op & CEPH_MDS_OP_WRITE) || | |
198 | head.op == CEPH_MDS_OP_OPEN) // do not forward _any_ open request. | |
199 | return false; | |
200 | return true; | |
201 | } | |
202 | bool auth_is_best() { | |
203 | if ((head.op & CEPH_MDS_OP_WRITE) || head.op == CEPH_MDS_OP_OPEN || | |
f67539c2 | 204 | (head.op == CEPH_MDS_OP_GETATTR && (head.args.getattr.mask & CEPH_STAT_RSTAT)) || |
28e407b8 | 205 | head.op == CEPH_MDS_OP_READDIR || send_to_auth) |
7c673cae FG |
206 | return true; |
207 | return false; | |
208 | } | |
209 | ||
210 | void dump(Formatter *f) const; | |
211 | ||
212 | }; | |
213 | ||
214 | #endif |