]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: add infrastructure for delegating inos from the prealloc set
authorJeff Layton <jlayton@redhat.com>
Wed, 9 Oct 2019 14:06:07 +0000 (10:06 -0400)
committerJeff Layton <jlayton@redhat.com>
Sat, 11 Jan 2020 12:11:47 +0000 (07:11 -0500)
Add a new interval_set to Session to track which preallocated inos have
been delegated to the client. Alter take_ino to also remove inos from
that set if they are present there. Add a new routine to refill the
delegated_inos set from the prealloc_set.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
src/mds/Server.cc
src/mds/SessionMap.cc
src/mds/SessionMap.h

index b2b84b87fb04874afbfac4e2bf08d7867846ff8e..f9098e002d5bbd2f307f7ee310156692ae877642 100644 (file)
@@ -757,6 +757,7 @@ void Server::_session_logged(Session *session, uint64_t state_seq, bool open, ve
     ceph_assert(session->is_closing() || session->is_killing() ||
           session->is_opening()); // re-open closing session
     session->info.prealloc_inos.subtract(inos);
+    session->delegated_inos.clear();
     mds->inotable->apply_release_ids(inos);
     ceph_assert(mds->inotable->get_version() == piv);
   }
@@ -3164,8 +3165,7 @@ CInode* Server::prepare_new_inode(MDRequestRef& mdr, CDir *dir, inodeno_t useino
   bool allow_prealloc_inos = mdr->session->is_open();
 
   // assign ino
-  if (allow_prealloc_inos &&
-      mdr->session->info.prealloc_inos.size()) {
+  if (allow_prealloc_inos && mdr->session->get_num_prealloc_inos()) {
     mdr->used_prealloc_ino = 
       in->inode.ino = mdr->session->take_ino(useino);  // prealloc -> used
     mds->sessionmap.mark_projected(mdr->session);
index 077ae944fc3ead4631d7a41be5b652cadbb51ee8..317e04ef1d25297c74dff644cba291efc9a68b8f 100644 (file)
@@ -79,6 +79,7 @@ void SessionMap::dump()
             << " state " << p->second->get_state_name()
             << " completed " << p->second->info.completed_requests
             << " prealloc_inos " << p->second->info.prealloc_inos
+            << " delegated_inos " << p->second->delegated_inos
             << " used_inos " << p->second->info.used_inos
             << dendl;
 }
@@ -627,6 +628,7 @@ void SessionMap::wipe_ino_prealloc()
        p != session_map.end(); 
        ++p) {
     p->second->pending_prealloc_inos.clear();
+    p->second->delegated_inos.clear();
     p->second->info.prealloc_inos.clear();
     p->second->info.used_inos.clear();
   }
index 3b0c7fe255d3cce288f5b6746b8bff5f55a90b1e..da1b30d8b95f648232d79cbe609dca247fe5a1ce 100644 (file)
@@ -176,20 +176,63 @@ public:
     ceph_assert(!info.prealloc_inos.empty());
 
     if (ino) {
-      if (info.prealloc_inos.contains(ino))
+      if (info.prealloc_inos.contains(ino)) {
        info.prealloc_inos.erase(ino);
-      else
+       if (delegated_inos.contains(ino))
+         delegated_inos.erase(ino);
+      } else {
        ino = 0;
+      }
     }
     if (!ino) {
-      ino = info.prealloc_inos.range_start();
-      info.prealloc_inos.erase(ino);
+      /* Grab first prealloc_ino that isn't delegated */
+      for (const auto& [start, len] : info.prealloc_inos) {
+       for (auto i = start ; i < start + len ; i += 1) {
+         inodeno_t dstart, dlen;
+         if (!delegated_inos.contains(i, &dstart, &dlen)) {
+           ino = i;
+           info.prealloc_inos.erase(ino);
+           break;
+         }
+         /* skip to end of delegated interval */
+         i = dstart + dlen - 1;
+       }
+       if (ino)
+         break;
+      }
     }
+    ceph_assert(ino);
     info.used_inos.insert(ino, 1);
     return ino;
   }
+  void delegate_inos(int want, interval_set<inodeno_t>& newinos) {
+    want -= (int)delegated_inos.size();
+    if (want <= 0)
+      return;
+
+    for (const auto& [start, len] : info.prealloc_inos) {
+      for (auto i = start ; i < start + len ; i += 1) {
+       inodeno_t dstart, dlen;
+       if (!delegated_inos.contains(i, &dstart, &dlen)) {
+         delegated_inos.insert(i);
+         newinos.insert(i);
+         if (--want == 0)
+            return;
+       } else {
+         /* skip to end of delegated interval */
+         i = dstart + dlen - 1;
+       }
+      }
+    }
+  }
+
+  // sans any delegated ones
+  int get_num_prealloc_inos() const {
+    return info.prealloc_inos.size() - delegated_inos.size();
+  }
+
   int get_num_projected_prealloc_inos() const {
-    return info.prealloc_inos.size() + pending_prealloc_inos.size();
+    return get_num_prealloc_inos() + pending_prealloc_inos.size();
   }
 
   client_t get_client() const {
@@ -362,6 +405,7 @@ public:
 
   void clear() {
     pending_prealloc_inos.clear();
+    delegated_inos.clear();
     info.clear_meta();
 
     cap_push_seq = 0;
@@ -382,6 +426,7 @@ public:
   mutable elist<MDRequestImpl*> requests;
 
   interval_set<inodeno_t> pending_prealloc_inos; // journaling prealloc, will be added to prealloc_inos
+  interval_set<inodeno_t> delegated_inos; // hand these out to client
 
   xlist<Capability*> caps;     // inodes with caps; front=most recently used
   xlist<ClientLease*> leases;  // metadata leases to clients