From: Jeff Layton Date: Wed, 9 Oct 2019 14:06:07 +0000 (-0400) Subject: mds: add infrastructure for delegating inos from the prealloc set X-Git-Tag: v15.1.0~128^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=029abbdf3319c7806c5fa4f9fc74b7e8ca613ad2;p=ceph.git mds: add infrastructure for delegating inos from the prealloc set 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 --- diff --git a/src/mds/Server.cc b/src/mds/Server.cc index b2b84b87fb04..f9098e002d5b 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -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); diff --git a/src/mds/SessionMap.cc b/src/mds/SessionMap.cc index 077ae944fc3e..317e04ef1d25 100644 --- a/src/mds/SessionMap.cc +++ b/src/mds/SessionMap.cc @@ -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(); } diff --git a/src/mds/SessionMap.h b/src/mds/SessionMap.h index 3b0c7fe255d3..da1b30d8b95f 100644 --- a/src/mds/SessionMap.h +++ b/src/mds/SessionMap.h @@ -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& 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 requests; interval_set pending_prealloc_inos; // journaling prealloc, will be added to prealloc_inos + interval_set delegated_inos; // hand these out to client xlist caps; // inodes with caps; front=most recently used xlist leases; // metadata leases to clients