From: Sage Weil Date: Fri, 8 Mar 2013 00:33:12 +0000 (-0800) Subject: mds: track created inos with completed request ids in session info X-Git-Tag: v0.60~121^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=0bcf2ac081b8386fe00387b654aa5676a7902c80;p=ceph.git 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 --- diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 08339ea9d4e..da2c03447f4 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 702a0b5dec8..ae975e69014 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 0ca7850cf54..5b3bd71c107 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 65e16bf80da..5b529ebf5ed 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 a67ff254984..55d7cedb2e3 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