From 0bcf2ac081b8386fe00387b654aa5676a7902c80 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 7 Mar 2013 16:33:12 -0800 Subject: [PATCH] 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 --- src/mds/Server.cc | 9 +++++---- src/mds/SessionMap.h | 24 +++++++++++------------- src/mds/journal.cc | 18 +++++++++++++----- src/mds/mdstypes.cc | 29 +++++++++++++++++++++-------- src/mds/mdstypes.h | 2 +- 5 files changed, 51 insertions(+), 31 deletions(-) diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 08339ea9d4ea3..da2c03447f4c0 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -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); diff --git a/src/mds/SessionMap.h b/src/mds/SessionMap.h index 702a0b5dec8fa..ae975e690142c 100644 --- a/src/mds/SessionMap.h +++ b/src/mds/SessionMap.h @@ -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::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); diff --git a/src/mds/journal.cc b/src/mds/journal.cc index 0ca7850cf54eb..5b3bd71c107da 100644 --- a/src/mds/journal.cc +++ b/src/mds/journal.cc @@ -1303,13 +1303,21 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg, MDSlaveUpdate *slaveup) // client requests for (list >::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); diff --git a/src/mds/mdstypes.cc b/src/mds/mdstypes.cc index 65e16bf80da19..5b529ebf5ed70 100644 --- a/src/mds/mdstypes.cc +++ b/src/mds/mdstypes.cc @@ -519,7 +519,7 @@ void old_rstat_t::generate_test_instances(list& 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 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::const_iterator p = completed_requests.begin(); + for (map::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& 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 diff --git a/src/mds/mdstypes.h b/src/mds/mdstypes.h index a67ff254984cd..55d7cedb2e34f 100644 --- a/src/mds/mdstypes.h +++ b/src/mds/mdstypes.h @@ -484,7 +484,7 @@ inline ostream& operator<<(ostream& out, const old_rstat_t& o) { struct session_info_t { entity_inst_t inst; - set completed_requests; + map completed_requests; interval_set prealloc_inos; // preallocated, ready to use. interval_set used_inos; // journaling use -- 2.39.5