]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: track created inos with completed request ids in session info
authorSage Weil <sage@inktank.com>
Fri, 8 Mar 2013 00:33:12 +0000 (16:33 -0800)
committerSage Weil <sage@inktank.com>
Fri, 8 Mar 2013 01:51:56 +0000 (17:51 -0800)
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>
src/mds/Server.cc
src/mds/SessionMap.h
src/mds/journal.cc
src/mds/mdstypes.cc
src/mds/mdstypes.h

index 08339ea9d4ea30c0aa4ff0144dca0613e461ccc3..da2c03447f4c0a310b004c5cd8a58781875ccb55 100644 (file)
@@ -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);
index 702a0b5dec8fa1812a3b025a3ae65ef0bacb1535..ae975e690142cdb60ff98b9278fca706012dc717 100644 (file)
@@ -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);
index 0ca7850cf54eb1861568d3daad66d4ba1fe343d8..5b3bd71c107da7c4d15f0a30ab5da10b215b93c0 100644 (file)
@@ -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);
index 65e16bf80da193edc1e4193af3d8e38746766fc0..5b529ebf5ed701e8287cb03c2eb05d1e4b9ac6cf 100644 (file)
@@ -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
index a67ff254984cd94f4227c24fd71d4905819aa44b..55d7cedb2e34f0f15e1fd14c240b94be9faa744a 100644 (file)
@@ -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