]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: properly close session when inodes are still being preallocated
authorSage Weil <sage@newdream.net>
Mon, 19 Jan 2009 23:04:55 +0000 (15:04 -0800)
committerSage Weil <sage@newdream.net>
Mon, 19 Jan 2009 23:04:55 +0000 (15:04 -0800)
src/mds/InoTable.cc
src/mds/Server.cc
src/mds/SessionMap.h

index b95e0ed2985bff37aebd141d31d25849c836531c..7dde6b29b860f9853051b65d4e205695579a81bc 100644 (file)
@@ -48,35 +48,35 @@ void InoTable::reset_state()
 
 inodeno_t InoTable::project_alloc_id(inodeno_t id) 
 {
+  dout(10) << "project_alloc_id " << id << " to " << projected_free << "/" << free << dendl;
   assert(is_active());
   if (!id)
     id = projected_free.start();
   projected_free.erase(id);
-  dout(10) << "project_alloc_id " << id << dendl;
   ++projected_version;
   return id;
 }
 void InoTable::apply_alloc_id(inodeno_t id)
 {
-  dout(10) << "apply_alloc_id " << id << dendl;
+  dout(10) << "apply_alloc_id " << id << " to " << projected_free << "/" << free << dendl;
   free.erase(id);
   ++version;
 }
 
 void InoTable::project_alloc_ids(deque<inodeno_t>& ids, int want) 
 {
+  dout(10) << "project_alloc_ids " << ids << " to " << projected_free << "/" << free << dendl;
   assert(is_active());
   for (int i=0; i<want; i++) {
     inodeno_t id = projected_free.start();
     projected_free.erase(id);
     ids.push_back(id);
   }
-  dout(10) << "project_alloc_ids " << ids << dendl;
   ++projected_version;
 }
 void InoTable::apply_alloc_ids(deque<inodeno_t>& ids)
 {
-  dout(10) << "apply_alloc_ids " << ids << dendl;
+  dout(10) << "apply_alloc_ids " << ids << " to " << projected_free << "/" << free << dendl;
   for (deque<inodeno_t>::iterator p = ids.begin();
        p != ids.end();
        p++) 
@@ -87,14 +87,14 @@ void InoTable::apply_alloc_ids(deque<inodeno_t>& ids)
 
 void InoTable::project_release_ids(deque<inodeno_t>& ids) 
 {
-  dout(10) << "project_release_ids " << ids << dendl;
+  dout(10) << "project_release_ids " << ids << " to " << projected_free << "/" << free << dendl;
   for (deque<inodeno_t>::iterator p = ids.begin(); p != ids.end(); p++)
     projected_free.insert(*p);
   ++projected_version;
 }
 void InoTable::apply_release_ids(deque<inodeno_t>& ids) 
 {
-  dout(10) << "apply_release_ids " << ids << dendl;
+  dout(10) << "apply_release_ids " << ids << " to " << projected_free << "/" << free << dendl;
   for (deque<inodeno_t>::iterator p = ids.begin(); p != ids.end(); p++)
     free.insert(*p);
   ++version;
index e8d2c8e0a7b4203daa184c20f8bca2fd1377ba19..7bb850bec7cb87901dd2e6d9de6e4d1eeca1455b 100644 (file)
@@ -137,7 +137,9 @@ public:
   C_MDS_session_finish(MDS *m, Session *se, bool s, version_t mv) :
     mds(m), session(se), open(s), cmapv(mv), inotablev(0) { }
   C_MDS_session_finish(MDS *m, Session *se, bool s, version_t mv, deque<inodeno_t>& i, version_t iv) :
-    mds(m), session(se), open(s), cmapv(mv), inos(i), inotablev(iv) { }
+    mds(m), session(se), open(s), cmapv(mv), inotablev(iv) {
+    inos.swap(i);
+  }
   void finish(int r) {
     assert(r == 0);
     mds->server->_session_logged(session, open, cmapv, inos, inotablev);
@@ -183,30 +185,36 @@ void Server::handle_client_session(MClientSession *m)
     break;
     
   case CEPH_SESSION_REQUEST_CLOSE:
-    if (!session || session->is_closing()) {
-      dout(10) << "already closing|dne, dropping this req" << dendl;
-      return;
-    }
-    if (m->seq < session->get_push_seq()) {
-      dout(10) << "old push seq " << m->seq << " < " << session->get_push_seq() 
-              << ", dropping" << dendl;
-      return;
-    }
-    if (m->seq != session->get_push_seq()) {
-      dout(10) << "old push seq " << m->seq << " != " << session->get_push_seq() 
-              << ", BUGGY!" << dendl;
-      assert(0);
+    {
+      if (!session || session->is_closing()) {
+       dout(10) << "already closing|dne, dropping this req" << dendl;
+       return;
+      }
+      if (m->seq < session->get_push_seq()) {
+       dout(10) << "old push seq " << m->seq << " < " << session->get_push_seq() 
+                << ", dropping" << dendl;
+       return;
+      }
+      if (m->seq != session->get_push_seq()) {
+       dout(10) << "old push seq " << m->seq << " != " << session->get_push_seq() 
+                << ", BUGGY!" << dendl;
+       assert(0);
+      }
+      mds->sessionmap.set_state(session, Session::STATE_CLOSING);
+      pv = ++mds->sessionmap.projected;
+      
+      deque<inodeno_t> both = session->prealloc_inos;
+      both.insert(both.end(), session->pending_prealloc_inos.begin(), 
+                 session->pending_prealloc_inos.end());
+      if (both.size()) {
+       mds->inotable->project_release_ids(both);
+       piv = mds->inotable->get_projected_version();
+      } else
+       piv = 0;
+      
+      mdlog->submit_entry(new ESession(m->get_source_inst(), false, pv, both, piv),
+                         new C_MDS_session_finish(mds, session, false, pv, both, piv));
     }
-    mds->sessionmap.set_state(session, Session::STATE_CLOSING);
-    pv = ++mds->sessionmap.projected;
-    if (session->prealloc_inos.size()) {
-      assert(session->projected_inos == 0);
-      mds->inotable->project_release_ids(session->prealloc_inos);
-      piv = mds->inotable->get_projected_version();
-    } else
-      piv = 0;
-    mdlog->submit_entry(new ESession(m->get_source_inst(), false, pv, session->prealloc_inos, piv),
-                       new C_MDS_session_finish(mds, session, false, pv, session->prealloc_inos, piv));
     break;
 
   default:
@@ -1365,11 +1373,12 @@ CInode* Server::prepare_new_inode(MDRequest *mdr, CDir *dir, inodeno_t useino)
     assert(0); // just for now.
   }
     
-  int want = g_conf.mds_client_prealloc_inos - mdr->session->get_num_projected_prealloc_inos();
-  if (want > 0) {
-    mds->inotable->project_alloc_ids(mdr->prealloc_inos, want);
+  int got = g_conf.mds_client_prealloc_inos - mdr->session->get_num_projected_prealloc_inos();
+  if (got > 0) {
+    mds->inotable->project_alloc_ids(mdr->prealloc_inos, got);
     assert(mdr->prealloc_inos.size());  // or else fix projected increment semantics
-    mdr->session->projected_inos += mdr->prealloc_inos.size();
+    mdr->session->pending_prealloc_inos.insert(mdr->session->pending_prealloc_inos.end(),
+                                              mdr->prealloc_inos.begin(), mdr->prealloc_inos.end());
     mds->sessionmap.projected++;
     dout(10) << "prepare_new_inode prealloc " << mdr->prealloc_inos << dendl;
   }
@@ -1412,9 +1421,11 @@ void Server::apply_allocated_inos(MDRequest *mdr)
   if (mdr->prealloc_inos.size()) {
     for (deque<inodeno_t>::iterator p = mdr->prealloc_inos.begin();
         p != mdr->prealloc_inos.end();
-        p++)
-      session->prealloc_inos.push_back(*p);
-    session->projected_inos -= mdr->prealloc_inos.size();
+        p++) {
+      assert(session->pending_prealloc_inos.front() == *p);
+      session->prealloc_inos.push_back(session->pending_prealloc_inos.front());
+      session->pending_prealloc_inos.pop_front();
+    }
     mds->sessionmap.version++;
     mds->inotable->apply_alloc_ids(mdr->prealloc_inos);
   }
index 69b518f5298497e67957f33ff11ae151ce33684b..c58b6e0673980580cc5fc8d0134d52889f3849e3 100644 (file)
@@ -52,7 +52,7 @@ public:
   entity_inst_t inst;
   xlist<Session*>::item session_list_item;
 
-  int projected_inos;               // journaling prealloc, will be added to prealloc_inos
+  deque<inodeno_t> pending_prealloc_inos; // journaling prealloc, will be added to prealloc_inos
   deque<inodeno_t> prealloc_inos;   // preallocated, ready to use.
   deque<inodeno_t> used_inos;       // journaling use
 
@@ -77,7 +77,7 @@ public:
     return ino;
   }
   int get_num_projected_prealloc_inos() {
-    return prealloc_inos.size() + projected_inos;
+    return prealloc_inos.size() + pending_prealloc_inos.size();
   }
 
   int get_client() { return inst.name.num(); }
@@ -143,7 +143,6 @@ public:
   Session() : 
     state(STATE_UNDEF), 
     session_list_item(this),
-    projected_inos(0),
     cap_push_seq(0) { }
 
   void encode(bufferlist& bl) const {