struct MetaRequest {
private:
InodeRef _inode, _old_inode, _other_inode;
- Dentry *_dentry; //associated with path
- Dentry *_old_dentry; //associated with path2
- int abort_rc;
+ Dentry *_dentry = NULL; //associated with path
+ Dentry *_old_dentry = NULL; //associated with path2
+ int abort_rc = 0;
public:
- uint64_t tid;
+ ceph::coarse_mono_time created = ceph::coarse_mono_clock::zero();
+ uint64_t tid = 0;
utime_t op_stamp;
ceph_mds_request_head head;
filepath path, path2;
std::string alternate_name;
+ std::vector<uint8_t> fscrypt_auth;
+ std::vector<uint8_t> fscrypt_file;
bufferlist data;
- int inode_drop; //the inode caps this operation will drop
- int inode_unless; //unless we have these caps already
- int old_inode_drop, old_inode_unless;
- int dentry_drop, dentry_unless;
- int old_dentry_drop, old_dentry_unless;
- int other_inode_drop, other_inode_unless;
- vector<MClientRequest::Release> cap_releases;
-
- int regetattr_mask; // getattr mask if i need to re-stat after a traceless reply
+ int inode_drop = 0; //the inode caps this operation will drop
+ int inode_unless = 0; //unless we have these caps already
+ int old_inode_drop = 0, old_inode_unless = 0;
+ int dentry_drop = 0, dentry_unless = 0;
+ int old_dentry_drop = 0, old_dentry_unless = 0;
+ int other_inode_drop = 0, other_inode_unless = 0;
+ std::vector<MClientRequest::Release> cap_releases;
+
+ int regetattr_mask = 0; // getattr mask if i need to re-stat after a traceless reply
utime_t sent_stamp;
- mds_rank_t mds; // who i am asking
- mds_rank_t resend_mds; // someone wants you to (re)send the request here
- bool send_to_auth; // must send to auth mds
- __u32 sent_on_mseq; // mseq at last submission of this request
- int num_fwd; // # of times i've been forwarded
- int retry_attempt;
+ mds_rank_t mds = -1; // who i am asking
+ mds_rank_t resend_mds = -1; // someone wants you to (re)send the request here
+ bool send_to_auth = false; // must send to auth mds
+ __u32 sent_on_mseq = 0; // mseq at last submission of this request
+ int num_fwd = 0; // # of times i've been forwarded
+ int retry_attempt = 0;
std::atomic<uint64_t> ref = { 1 };
- ceph::cref_t<MClientReply> reply; // the reply
- bool kick;
- bool success;
-
+ ceph::cref_t<MClientReply> reply = NULL; // the reply
+ bool kick = false;
+ bool success = false;
+
// readdir result
- dir_result_t *dirp;
+ dir_result_t *dirp = NULL;
//possible responses
- bool got_unsafe;
+ bool got_unsafe = false;
xlist<MetaRequest*>::item item;
xlist<MetaRequest*>::item unsafe_item;
xlist<MetaRequest*>::item unsafe_dir_item;
xlist<MetaRequest*>::item unsafe_target_item;
- ceph::condition_variable *caller_cond; // who to take up
- ceph::condition_variable *dispatch_cond; // who to kick back
- list<ceph::condition_variable*> waitfor_safe;
+ ceph::condition_variable *caller_cond = NULL; // who to take up
+ ceph::condition_variable *dispatch_cond = NULL; // who to kick back
+ std::list<ceph::condition_variable*> waitfor_safe;
InodeRef target;
UserPerm perms;
explicit MetaRequest(int op) :
- _dentry(NULL), _old_dentry(NULL), abort_rc(0),
- tid(0),
- inode_drop(0), inode_unless(0),
- old_inode_drop(0), old_inode_unless(0),
- dentry_drop(0), dentry_unless(0),
- old_dentry_drop(0), old_dentry_unless(0),
- other_inode_drop(0), other_inode_unless(0),
- regetattr_mask(0),
- mds(-1), resend_mds(-1), send_to_auth(false), sent_on_mseq(0),
- num_fwd(0), retry_attempt(0),
- reply(0),
- kick(false), success(false), dirp(NULL),
- got_unsafe(false), item(this), unsafe_item(this),
- unsafe_dir_item(this), unsafe_target_item(this),
- caller_cond(0), dispatch_cond(0) {
+ item(this), unsafe_item(this), unsafe_dir_item(this),
+ unsafe_target_item(this) {
memset(&head, 0, sizeof(head));
head.op = op;
}
// normal fields
void set_tid(ceph_tid_t t) { tid = t; }
void set_oldest_client_tid(ceph_tid_t t) { head.oldest_client_tid = t; }
- void inc_num_fwd() { head.num_fwd = head.num_fwd + 1; }
- void set_retry_attempt(int a) { head.num_retry = a; }
+ void inc_num_fwd() { head.ext_num_fwd = head.ext_num_fwd + 1; }
+ void set_retry_attempt(int a) { head.ext_num_retry = a; }
void set_filepath(const filepath& fp) { path = fp; }
void set_filepath2(const filepath& fp) { path2 = fp; }
void set_alternate_name(std::string an) { alternate_name = an; }
void set_string2(const char *s) { path2.set_path(std::string_view(s), 0); }
void set_caller_perms(const UserPerm& _perms) {
- perms.shallow_copy(_perms);
+ perms = _perms;
head.caller_uid = perms.uid();
head.caller_gid = perms.gid();
}
return false;
return true;
}
- bool auth_is_best() {
- if ((head.op & CEPH_MDS_OP_WRITE) || head.op == CEPH_MDS_OP_OPEN ||
- (head.op == CEPH_MDS_OP_GETATTR && (head.args.getattr.mask & CEPH_STAT_RSTAT)) ||
- head.op == CEPH_MDS_OP_READDIR || send_to_auth)
+ bool auth_is_best(int issued) {
+ if (send_to_auth)
+ return true;
+
+ /* Any write op ? */
+ if (head.op & CEPH_MDS_OP_WRITE)
return true;
- return false;
+
+ switch (head.op) {
+ case CEPH_MDS_OP_OPEN:
+ case CEPH_MDS_OP_READDIR:
+ return true;
+ case CEPH_MDS_OP_GETATTR:
+ /*
+ * If any 'x' caps is issued we can just choose the auth MDS
+ * instead of the random replica MDSes. Because only when the
+ * Locker is in LOCK_EXEC state will the loner client could
+ * get the 'x' caps. And if we send the getattr requests to
+ * any replica MDS it must auth pin and tries to rdlock from
+ * the auth MDS, and then the auth MDS need to do the Locker
+ * state transition to LOCK_SYNC. And after that the lock state
+ * will change back.
+ *
+ * This cost much when doing the Locker state transition and
+ * usually will need to revoke caps from clients.
+ *
+ * And for the 'Xs' caps for getxattr we will also choose the
+ * auth MDS, because the MDS side code is buggy due to setxattr
+ * won't notify the replica MDSes when the values changed and
+ * the replica MDS will return the old values. Though we will
+ * fix it in MDS code, but this still makes sense for old ceph.
+ */
+ if (((head.args.getattr.mask & CEPH_CAP_ANY_SHARED) &&
+ (issued & CEPH_CAP_ANY_EXCL)) ||
+ (head.args.getattr.mask & (CEPH_STAT_RSTAT | CEPH_STAT_CAP_XATTR)))
+ return true;
+ default:
+ return false;
+ }
}
void dump(Formatter *f) const;