]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: use intrusive set for ClientLease tracking 57911/head
authorGarry Drankovich <garry.drankovich@clyso.com>
Thu, 6 Jun 2024 10:17:00 +0000 (13:17 +0300)
committerGarry Drankovich <garry.drankovich@clyso.com>
Mon, 24 Jun 2024 17:18:44 +0000 (20:18 +0300)
This allows to avoid additional redundant lookups in CDentry::client_leases
for some scenarios, e.g.:
* CDentry::remove_client_lease() is called from CDentry::remove_client_leases().
* CDentry::remove_client_lease() is called from Locker::remove_stale_leases()
* CDentry::remove_client_lease() is called from Locker::process_request_cap_release()

And a few similar cases.
In all of them a caller has a pointer to ClientLease object but has to
perform another lookup to remove that lease.

Signed-off-by: Garry Drankovich <garry.drankovich@clyso.com>
src/mds/CDentry.cc
src/mds/CDentry.h
src/mds/Locker.cc

index b1a294be5af89ea6e7428e650ee17414557544e2..58000022439d9f0574644331739fcfdd3b9ff6b4 100644 (file)
@@ -500,6 +500,8 @@ void CDentry::decode_lock_state(int type, const bufferlist& bl)
 }
 
 
+MEMPOOL_DEFINE_OBJECT_FACTORY(ClientLease, mds_client_lease, mds_co);
+
 client_t ClientLease::get_client() const
 {
   return session->get_client();
@@ -508,17 +510,19 @@ client_t ClientLease::get_client() const
 ClientLease *CDentry::add_client_lease(Session *session)
 {
   client_t client = session->get_client();
-  auto em = client_leases.emplace(std::piecewise_construct,
-                                 std::forward_as_tuple(client),
-                                 std::forward_as_tuple(this, session));
-  ClientLease *l = &em.first->second;
-  if (em.second) {
+  ClientLease* l = nullptr;
+  auto it = client_leases.lower_bound(client);
+  if (it == client_leases.end() || it->get_client() != client) {
+    l = new ClientLease(this, session);
     dout(20) << __func__ << " client." << client << " on " << lock << dendl;
-    if (client_leases.size() == 1) {
+    if (client_leases.empty()) {
       get(PIN_CLIENTLEASE);
       lock.get_client_lease();
     }
+    client_leases.insert_before(it, *l);
     l->seq = ++session->lease_seq;
+  } else {
+    l = &(*it);
   }
   return l;
 }
@@ -528,12 +532,12 @@ void CDentry::remove_client_lease(ClientLease *l, Locker *locker)
   ceph_assert(l->parent == this);
 
   bool gather = false;
-  client_t client = l->get_client();
-  dout(20) << __func__ << " client." << client << " on " << lock << dendl;
+  dout(20) << __func__ << " client." << l->get_client() << " on " << lock << dendl;
 
   l->item_lease.remove_myself();
   l->item_session_lease.remove_myself();
-  client_leases.erase(client);
+  client_leases.erase(client_leases.iterator_to(*l));
+  delete l;
 
   if (client_leases.empty()) {
     gather = !lock.is_stable();
@@ -548,7 +552,7 @@ void CDentry::remove_client_lease(ClientLease *l, Locker *locker)
 void CDentry::remove_client_leases(Locker *locker)
 {
   while (!client_leases.empty())
-    remove_client_lease(&client_leases.begin()->second, locker);
+    remove_client_lease(&(*client_leases.begin()), locker);
 }
 
 void CDentry::_put()
index e863daef3999129044ac98c9e48eb0c024988402..ca36da0354f3847ea8641c00cde69166051bb023 100644 (file)
@@ -17,7 +17,6 @@
 
 #include <string>
 #include <string_view>
-#include <set>
 
 #include "include/counter.h"
 #include "include/types.h"
@@ -25,6 +24,7 @@
 #include "include/lru.h"
 #include "include/elist.h"
 #include "include/filepath.h"
+#include <boost/intrusive/set.hpp>
 
 #include "BatchOp.h"
 #include "MDSCacheObject.h"
 #include "ScrubHeader.h"
 
 class CInode;
-class CDentry;
 class CDir;
 class Locker;
 class CDentry;
 class LogSegment;
 class Session;
 
-struct ClientLease {
+struct ClientLease : public boost::intrusive::set_base_hook<>
+{
+  MEMPOOL_CLASS_HELPERS();
+
   ClientLease(CDentry *p, Session *s) :
     parent(p), session(s),
     item_session_lease(this),
@@ -57,6 +59,13 @@ struct ClientLease {
   xlist<ClientLease*>::item item_session_lease; // per-session list
   xlist<ClientLease*>::item item_lease;         // global list
 };
+struct client_is_key
+{
+  typedef client_t type;
+  const type operator() (const ClientLease& l) const {
+    return l.get_client();
+  }
+};
 
 // define an ordering
 bool operator<(const CDentry& l, const CDentry& r);
@@ -346,13 +355,13 @@ public:
   const ClientLease *get_client_lease(client_t c) const {
     auto it = client_leases.find(c);
     if (it != client_leases.end())
-      return &it->second;
+      return &(*it);
     return nullptr;
   }
   ClientLease *get_client_lease(client_t c) {
     auto it = client_leases.find(c);
     if (it != client_leases.end())
-      return &it->second;
+      return &(*it);
     return nullptr;
   }
   bool have_client_lease(client_t c) const {
@@ -388,7 +397,10 @@ public:
   SimpleLock lock; // FIXME referenced containers not in mempool
   LocalLockC versionlock; // FIXME referenced containers not in mempool
 
-  mempool::mds_co::map<client_t, ClientLease> client_leases;
+  typedef boost::intrusive::set<
+    ClientLease, boost::intrusive::key_of_value<client_is_key>> ClientLeaseMap;
+  ClientLeaseMap client_leases;
+
   std::map<int, std::unique_ptr<BatchOp>> batch_ops;
 
   ceph_tid_t reintegration_reqid = 0;
index 5add82cf85b38001f8add5084b506b859db3e1a6..e79a4a86bf17eb1d396c6e9674c0b22ca064d3b7 100644 (file)
@@ -4529,8 +4529,7 @@ void Locker::issue_client_lease(CDentry *dn, CInode *in, const MDRequestRef& mdr
 void Locker::revoke_client_leases(SimpleLock *lock)
 {
   CDentry *dn = static_cast<CDentry*>(lock->get_parent());
-  for (auto& p : dn->client_leases) {
-    ClientLease *l = &p.second;
+  for (ClientLease& l : dn->client_leases) {
     
     ceph_assert(lock->get_type() == CEPH_LOCK_DN);
 
@@ -4539,8 +4538,8 @@ void Locker::revoke_client_leases(SimpleLock *lock)
 
     // i should also revoke the dir ICONTENT lease, if they have it!
     CInode *diri = dn->get_dir()->get_inode();
-    auto lease = make_message<MClientLease>(CEPH_MDS_LEASE_REVOKE, l->seq, mask, diri->ino(), diri->first, CEPH_NOSNAP, dn->get_name());
-    mds->send_message_client_counted(lease, l->session);
+    auto lease = make_message<MClientLease>(CEPH_MDS_LEASE_REVOKE, l.seq, mask, diri->ino(), diri->first, CEPH_NOSNAP, dn->get_name());
+    mds->send_message_client_counted(lease, l.session);
   }
 }