mirror of
https://github.com/ceph/ceph
synced 2025-02-22 18:47:18 +00:00
mds: track created inos with completed request ids in session info
Along with each session completed request (tid), also track the created ino (if any). This will be used to pass back to the client when they replay requests in the next patch. Do not bother making this a backward compatible encoding. The only benefit is to allow ceph-mds code to run and then old mds code to run after it. Given all of the other incompat changes we *just* made, this is highly unlikely and not worth the code clutter. If we had spanned more releases or a stable release the story would be different. While we are here, inline the second add_completed_request() method variant since there is only a single caller and having it overloaded somewhat obscures what is going on. This also avoids a duplicate lookup in the session map in the have_session() check and then in the (old) helper. Signed-off-by: Sage Weil <sage@inktank.com>
This commit is contained in:
parent
977a1cb257
commit
0bcf2ac081
@ -871,7 +871,7 @@ void Server::reply_request(MDRequest *mdr, MClientReply *reply, CInode *tracei,
|
||||
|
||||
// note successful request in session map?
|
||||
if (req->may_write() && mdr->session && reply->get_result() == 0)
|
||||
mdr->session->add_completed_request(mdr->reqid.tid);
|
||||
mdr->session->add_completed_request(mdr->reqid.tid, mdr->alloc_ino);
|
||||
|
||||
// give any preallocated inos to the session
|
||||
apply_allocated_inos(mdr);
|
||||
@ -1096,7 +1096,8 @@ void Server::handle_client_request(MClientRequest *req)
|
||||
req->get_op() != CEPH_MDS_OP_OPEN &&
|
||||
req->get_op() != CEPH_MDS_OP_CREATE)) {
|
||||
assert(session);
|
||||
if (session->have_completed_request(req->get_reqid().tid)) {
|
||||
inodeno_t created;
|
||||
if (session->have_completed_request(req->get_reqid().tid, &created)) {
|
||||
dout(5) << "already completed " << req->get_reqid() << dendl;
|
||||
mds->messenger->send_message(new MClientReply(req, 0), req->get_connection());
|
||||
|
||||
@ -1209,7 +1210,7 @@ void Server::dispatch_client_request(MDRequest *mdr)
|
||||
// funky.
|
||||
case CEPH_MDS_OP_CREATE:
|
||||
if (req->get_retry_attempt() &&
|
||||
mdr->session->have_completed_request(req->get_reqid().tid))
|
||||
mdr->session->have_completed_request(req->get_reqid().tid, NULL))
|
||||
handle_client_open(mdr); // already created.. just open
|
||||
else
|
||||
handle_client_openc(mdr);
|
||||
@ -2521,7 +2522,7 @@ void Server::handle_client_open(MDRequest *mdr)
|
||||
// O_TRUNC
|
||||
if ((flags & O_TRUNC) &&
|
||||
!(req->get_retry_attempt() &&
|
||||
mdr->session->have_completed_request(req->get_reqid().tid))) {
|
||||
mdr->session->have_completed_request(req->get_reqid().tid, NULL))) {
|
||||
assert(cur->is_auth());
|
||||
|
||||
wrlocks.insert(&cur->filelock);
|
||||
|
@ -168,17 +168,22 @@ private:
|
||||
|
||||
|
||||
public:
|
||||
void add_completed_request(tid_t t) {
|
||||
info.completed_requests.insert(t);
|
||||
void add_completed_request(tid_t t, inodeno_t created) {
|
||||
info.completed_requests[t] = created;
|
||||
}
|
||||
void trim_completed_requests(tid_t mintid) {
|
||||
// trim
|
||||
while (!info.completed_requests.empty() &&
|
||||
(mintid == 0 || *info.completed_requests.begin() < mintid))
|
||||
(mintid == 0 || info.completed_requests.begin()->first < mintid))
|
||||
info.completed_requests.erase(info.completed_requests.begin());
|
||||
}
|
||||
bool have_completed_request(tid_t tid) const {
|
||||
return info.completed_requests.count(tid);
|
||||
bool have_completed_request(tid_t tid, inodeno_t *pcreated) const {
|
||||
map<tid_t,inodeno_t>::const_iterator p = info.completed_requests.find(tid);
|
||||
if (p == info.completed_requests.end())
|
||||
return false;
|
||||
if (pcreated)
|
||||
*pcreated = p->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -349,14 +354,7 @@ public:
|
||||
}
|
||||
bool have_completed_request(metareqid_t rid) {
|
||||
Session *session = get_session(rid.name);
|
||||
return session && session->have_completed_request(rid.tid);
|
||||
}
|
||||
void add_completed_request(metareqid_t rid, tid_t tid=0) {
|
||||
Session *session = get_session(rid.name);
|
||||
assert(session);
|
||||
session->add_completed_request(rid.tid);
|
||||
if (tid)
|
||||
session->trim_completed_requests(tid);
|
||||
return session && session->have_completed_request(rid.tid, NULL);
|
||||
}
|
||||
void trim_completed_requests(entity_name_t c, tid_t tid) {
|
||||
Session *session = get_session(c);
|
||||
|
@ -1303,13 +1303,21 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg, MDSlaveUpdate *slaveup)
|
||||
// client requests
|
||||
for (list<pair<metareqid_t, uint64_t> >::iterator p = client_reqs.begin();
|
||||
p != client_reqs.end();
|
||||
++p)
|
||||
++p) {
|
||||
if (p->first.name.is_client()) {
|
||||
dout(10) << "EMetaBlob.replay request " << p->first << " " << p->second << dendl;
|
||||
if (mds->sessionmap.have_session(p->first.name))
|
||||
mds->sessionmap.add_completed_request(p->first, p->second);
|
||||
}
|
||||
dout(10) << "EMetaBlob.replay request " << p->first << " trim_to " << p->second << dendl;
|
||||
|
||||
// if we allocated an inode, there should be exactly one client request id.
|
||||
assert(allocated_ino == inodeno_t() || client_reqs.size() == 1);
|
||||
|
||||
Session *session = mds->sessionmap.get_session(p->first.name);
|
||||
if (session) {
|
||||
session->add_completed_request(p->first.tid, allocated_ino);
|
||||
if (p->second)
|
||||
session->trim_completed_requests(p->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update segment
|
||||
update_segment(logseg);
|
||||
|
@ -519,7 +519,7 @@ void old_rstat_t::generate_test_instances(list<old_rstat_t*>& ls)
|
||||
*/
|
||||
void session_info_t::encode(bufferlist& bl) const
|
||||
{
|
||||
ENCODE_START(2, 2, bl);
|
||||
ENCODE_START(3, 3, bl);
|
||||
::encode(inst, bl);
|
||||
::encode(completed_requests, bl);
|
||||
::encode(prealloc_inos, bl); // hacky, see below.
|
||||
@ -529,9 +529,18 @@ void session_info_t::encode(bufferlist& bl) const
|
||||
|
||||
void session_info_t::decode(bufferlist::iterator& p)
|
||||
{
|
||||
DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, p);
|
||||
DECODE_START_LEGACY_COMPAT_LEN(3, 2, 2, p);
|
||||
::decode(inst, p);
|
||||
::decode(completed_requests, p);
|
||||
if (struct_v == 2) {
|
||||
set<tid_t> s;
|
||||
::decode(completed_requests, p);
|
||||
while (!s.empty()) {
|
||||
completed_requests[*s.begin()] = inodeno_t();
|
||||
s.erase(s.begin());
|
||||
}
|
||||
} else {
|
||||
::decode(completed_requests, p);
|
||||
}
|
||||
::decode(prealloc_inos, p);
|
||||
::decode(used_inos, p);
|
||||
prealloc_inos.insert(used_inos);
|
||||
@ -544,10 +553,14 @@ void session_info_t::dump(Formatter *f) const
|
||||
f->dump_stream("inst") << inst;
|
||||
|
||||
f->open_array_section("completed_requests");
|
||||
for (set<tid_t>::const_iterator p = completed_requests.begin();
|
||||
for (map<tid_t,inodeno_t>::const_iterator p = completed_requests.begin();
|
||||
p != completed_requests.end();
|
||||
++p)
|
||||
f->dump_unsigned("tid", *p);
|
||||
++p) {
|
||||
f->open_object_section("request");
|
||||
f->dump_unsigned("tid", p->first);
|
||||
f->dump_stream("created_ino") << p->second;
|
||||
f->close_section();
|
||||
}
|
||||
f->close_section();
|
||||
|
||||
f->open_array_section("prealloc_inos");
|
||||
@ -578,8 +591,8 @@ void session_info_t::generate_test_instances(list<session_info_t*>& ls)
|
||||
ls.push_back(new session_info_t);
|
||||
ls.push_back(new session_info_t);
|
||||
ls.back()->inst = entity_inst_t(entity_name_t::MDS(12), entity_addr_t());
|
||||
ls.back()->completed_requests.insert(234);
|
||||
ls.back()->completed_requests.insert(237);
|
||||
ls.back()->completed_requests.insert(make_pair(234, inodeno_t(111222)));
|
||||
ls.back()->completed_requests.insert(make_pair(237, inodeno_t(222333)));
|
||||
ls.back()->prealloc_inos.insert(333, 12);
|
||||
ls.back()->prealloc_inos.insert(377, 112);
|
||||
// we can't add used inos; they're cleared on decode
|
||||
|
@ -484,7 +484,7 @@ inline ostream& operator<<(ostream& out, const old_rstat_t& o) {
|
||||
|
||||
struct session_info_t {
|
||||
entity_inst_t inst;
|
||||
set<tid_t> completed_requests;
|
||||
map<tid_t,inodeno_t> completed_requests;
|
||||
interval_set<inodeno_t> prealloc_inos; // preallocated, ready to use.
|
||||
interval_set<inodeno_t> used_inos; // journaling use
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user