1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #ifndef CEPH_CLIENT_METAREQUEST_H
5 #define CEPH_CLIENT_METAREQUEST_H
8 #include "include/types.h"
9 #include "include/xlist.h"
10 #include "include/filepath.h"
11 #include "mds/mdstypes.h"
15 #include "messages/MClientRequest.h"
16 #include "messages/MClientReply.h"
23 InodeRef _inode
, _old_inode
, _other_inode
;
24 Dentry
*_dentry
; //associated with path
25 Dentry
*_old_dentry
; //associated with path2
30 ceph_mds_request_head head
;
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
;
41 int regetattr_mask
; // getattr mask if i need to re-stat after a traceless reply
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
50 std::atomic
<uint64_t> ref
= { 1 };
52 ceph::cref_t
<MClientReply
> reply
; // the reply
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
;
67 ceph::condition_variable
*caller_cond
; // who to take up
68 ceph::condition_variable
*dispatch_cond
; // who to kick back
69 list
<ceph::condition_variable
*> waitfor_safe
;
74 explicit MetaRequest(int op
) :
75 _dentry(NULL
), _old_dentry(NULL
), abort_rc(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),
83 mds(-1), resend_mds(-1), send_to_auth(false), sent_on_mseq(0),
84 num_fwd(0), retry_attempt(0),
86 kick(false), success(false), dirp(NULL
),
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
));
96 * Prematurely terminate the request, such that callers
97 * to make_request will receive `rc` as their result.
101 ceph_assert(rc
!= 0);
106 * Whether abort() has been called for this request
108 inline bool aborted() const
110 return abort_rc
!= 0;
114 * Given that abort() has been called for this request, what `rc` was
117 int get_abort_code() const
122 void set_inode(Inode
*in
) {
128 void take_inode(InodeRef
*out
) {
131 void set_old_inode(Inode
*in
) {
135 return _old_inode
.get();
137 void take_old_inode(InodeRef
*out
) {
138 out
->swap(_old_inode
);
140 void set_other_inode(Inode
*in
) {
143 Inode
*other_inode() {
144 return _other_inode
.get();
146 void take_other_inode(InodeRef
*out
) {
147 out
->swap(_other_inode
);
149 void set_dentry(Dentry
*d
);
151 void set_old_dentry(Dentry
*d
);
152 Dentry
*old_dentry();
159 /// psuedo-private put method; use Client::put_request()
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
; }
172 void set_string2(const char *s
) { path2
.set_path(std::string_view(s
), 0); }
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();
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
;
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
; }
191 (head
.op
& CEPH_MDS_OP_WRITE
) ||
192 (head
.op
== CEPH_MDS_OP_OPEN
&& (head
.args
.open
.flags
& (O_CREAT
|O_TRUNC
)));
195 if ((head
.op
& CEPH_MDS_OP_WRITE
) ||
196 head
.op
== CEPH_MDS_OP_OPEN
) // do not forward _any_ open request.
200 bool auth_is_best() {
201 if ((head
.op
& CEPH_MDS_OP_WRITE
) || head
.op
== CEPH_MDS_OP_OPEN
||
202 head
.op
== CEPH_MDS_OP_READDIR
|| send_to_auth
)
207 void dump(Formatter
*f
) const;