1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
#ifndef CEPH_CLIENT_METAREQUEST_H
#define CEPH_CLIENT_METAREQUEST_H
#include "include/types.h"
#include "msg/msg_types.h"
#include "include/xlist.h"
#include "include/filepath.h"
#include "mds/mdstypes.h"
#include "common/Mutex.h"
#include "messages/MClientRequest.h"
class MClientReply;
class Inode;
class Dentry;
struct MetaRequest {
uint64_t tid;
ceph_mds_request_head head;
filepath path, path2;
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;
Inode *inode;
Inode *old_inode, *other_inode;
Dentry *dentry; //associated with path
Dentry *old_dentry; //associated with path2
utime_t sent_stamp;
int mds; // who i am asking
int 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;
int ref;
MClientReply *reply; // the reply
bool kick;
// readdir result
frag_t readdir_frag;
string readdir_start; // starting _after_ this name
uint64_t readdir_offset;
vector<pair<string,Inode*> > readdir_result;
bool readdir_end;
int readdir_num;
string readdir_last_name;
//possible responses
bool got_safe;
bool got_unsafe;
xlist<MetaRequest*>::item item;
xlist<MetaRequest*>::item unsafe_item;
Mutex lock; //for get/set sync
Cond *caller_cond; // who to take up
Cond *dispatch_cond; // who to kick back
Inode *target;
MetaRequest(int op) :
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),
inode(NULL), old_inode(NULL), other_inode(NULL),
dentry(NULL), old_dentry(NULL),
mds(-1), resend_mds(-1), send_to_auth(false), sent_on_mseq(0),
num_fwd(0), retry_attempt(0),
ref(1), reply(0),
kick(false),
readdir_offset(0), readdir_end(false), readdir_num(0),
got_safe(false), got_unsafe(false), item(this), unsafe_item(this),
lock("MetaRequest lock"),
caller_cond(0), dispatch_cond(0),
target(0) {
memset(&head, 0, sizeof(ceph_mds_request_head));
head.op = op;
}
~MetaRequest();
MetaRequest* get() {
++ref;
return this;
}
void put() {
if (--ref == 0)
delete this;
}
// normal fields
void set_tid(tid_t t) { tid = t; }
void set_oldest_client_tid(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 set_filepath(const filepath& fp) { path = fp; }
void set_filepath2(const filepath& fp) { path2 = fp; }
void set_string2(const char *s) { path2.set_path(s, 0); }
void set_caller_uid(unsigned u) { head.caller_uid = u; }
void set_caller_gid(unsigned g) { head.caller_gid = g; }
void set_data(const bufferlist &d) { data = d; }
void set_dentry_wanted() {
head.flags = head.flags | CEPH_MDS_FLAG_WANT_DENTRY;
}
int get_op() { return head.op; }
tid_t get_tid() { return tid; }
filepath& get_filepath() { return path; }
filepath& get_filepath2() { return path2; }
bool is_write() {
return
(head.op & CEPH_MDS_OP_WRITE) ||
(head.op == CEPH_MDS_OP_OPEN && !(head.args.open.flags & (O_CREAT|O_TRUNC))) ||
(head.op == CEPH_MDS_OP_CREATE && !(head.args.open.flags & (O_CREAT|O_TRUNC)));
}
bool can_forward() {
if (is_write() ||
head.op == CEPH_MDS_OP_OPEN || // do not forward _any_ open request.
head.op == CEPH_MDS_OP_CREATE) // do not forward _any_ open request.
return false;
return true;
}
bool auth_is_best() {
if (is_write())
return true;
if (head.op == CEPH_MDS_OP_OPEN ||
head.op == CEPH_MDS_OP_CREATE ||
head.op == CEPH_MDS_OP_READDIR)
return true;
return false;
}
void dump(Formatter *f) const;
};
#endif
|