]>
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" | |
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 |