Skip to content

Commit 2140fbf

Browse files
committed
mds: use intrusive set for ClientLease tracking
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 <[email protected]>
1 parent 0a4a5d3 commit 2140fbf

File tree

3 files changed

+35
-20
lines changed

3 files changed

+35
-20
lines changed

src/mds/CDentry.cc

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,8 @@ void CDentry::decode_lock_state(int type, const bufferlist& bl)
500500
}
501501

502502

503+
MEMPOOL_DEFINE_OBJECT_FACTORY(ClientLease, mds_client_lease, mds_co);
504+
503505
client_t ClientLease::get_client() const
504506
{
505507
return session->get_client();
@@ -508,17 +510,19 @@ client_t ClientLease::get_client() const
508510
ClientLease *CDentry::add_client_lease(Session *session)
509511
{
510512
client_t client = session->get_client();
511-
auto em = client_leases.emplace(std::piecewise_construct,
512-
std::forward_as_tuple(client),
513-
std::forward_as_tuple(this, session));
514-
ClientLease *l = &em.first->second;
515-
if (em.second) {
513+
ClientLease* l = nullptr;
514+
auto it = client_leases.lower_bound(client);
515+
if (it == client_leases.end() || it->get_client() != client) {
516+
l = new ClientLease(this, session);
516517
dout(20) << __func__ << " client." << client << " on " << lock << dendl;
517-
if (client_leases.size() == 1) {
518+
if (client_leases.empty()) {
518519
get(PIN_CLIENTLEASE);
519520
lock.get_client_lease();
520521
}
522+
client_leases.insert_before(it, *l);
521523
l->seq = ++session->lease_seq;
524+
} else {
525+
l = &(*it);
522526
}
523527
return l;
524528
}
@@ -528,12 +532,12 @@ void CDentry::remove_client_lease(ClientLease *l, Locker *locker)
528532
ceph_assert(l->parent == this);
529533

530534
bool gather = false;
531-
client_t client = l->get_client();
532-
dout(20) << __func__ << " client." << client << " on " << lock << dendl;
535+
dout(20) << __func__ << " client." << l->get_client() << " on " << lock << dendl;
533536

534537
l->item_lease.remove_myself();
535538
l->item_session_lease.remove_myself();
536-
client_leases.erase(client);
539+
client_leases.erase(client_leases.iterator_to(*l));
540+
delete l;
537541

538542
if (client_leases.empty()) {
539543
gather = !lock.is_stable();
@@ -548,7 +552,7 @@ void CDentry::remove_client_lease(ClientLease *l, Locker *locker)
548552
void CDentry::remove_client_leases(Locker *locker)
549553
{
550554
while (!client_leases.empty())
551-
remove_client_lease(&client_leases.begin()->second, locker);
555+
remove_client_lease(&(*client_leases.begin()), locker);
552556
}
553557

554558
void CDentry::_put()

src/mds/CDentry.h

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@
1717

1818
#include <string>
1919
#include <string_view>
20-
#include <set>
2120

2221
#include "include/counter.h"
2322
#include "include/types.h"
2423
#include "include/buffer_fwd.h"
2524
#include "include/lru.h"
2625
#include "include/elist.h"
2726
#include "include/filepath.h"
27+
#include <boost/intrusive/set.hpp>
2828

2929
#include "BatchOp.h"
3030
#include "MDSCacheObject.h"
@@ -34,14 +34,16 @@
3434
#include "ScrubHeader.h"
3535

3636
class CInode;
37-
class CDentry;
3837
class CDir;
3938
class Locker;
4039
class CDentry;
4140
class LogSegment;
4241
class Session;
4342

44-
struct ClientLease {
43+
struct ClientLease : public boost::intrusive::set_base_hook<>
44+
{
45+
MEMPOOL_CLASS_HELPERS();
46+
4547
ClientLease(CDentry *p, Session *s) :
4648
parent(p), session(s),
4749
item_session_lease(this),
@@ -57,6 +59,13 @@ struct ClientLease {
5759
xlist<ClientLease*>::item item_session_lease; // per-session list
5860
xlist<ClientLease*>::item item_lease; // global list
5961
};
62+
struct client_is_key
63+
{
64+
typedef client_t type;
65+
const type operator() (const ClientLease& l) const {
66+
return l.get_client();
67+
}
68+
};
6069

6170
// define an ordering
6271
bool operator<(const CDentry& l, const CDentry& r);
@@ -346,13 +355,13 @@ class CDentry : public MDSCacheObject, public LRUObject, public Counter<CDentry>
346355
const ClientLease *get_client_lease(client_t c) const {
347356
auto it = client_leases.find(c);
348357
if (it != client_leases.end())
349-
return &it->second;
358+
return &(*it);
350359
return nullptr;
351360
}
352361
ClientLease *get_client_lease(client_t c) {
353362
auto it = client_leases.find(c);
354363
if (it != client_leases.end())
355-
return &it->second;
364+
return &(*it);
356365
return nullptr;
357366
}
358367
bool have_client_lease(client_t c) const {
@@ -388,7 +397,10 @@ class CDentry : public MDSCacheObject, public LRUObject, public Counter<CDentry>
388397
SimpleLock lock; // FIXME referenced containers not in mempool
389398
LocalLockC versionlock; // FIXME referenced containers not in mempool
390399

391-
mempool::mds_co::map<client_t, ClientLease> client_leases;
400+
typedef boost::intrusive::set<
401+
ClientLease, boost::intrusive::key_of_value<client_is_key>> ClientLeaseMap;
402+
ClientLeaseMap client_leases;
403+
392404
std::map<int, std::unique_ptr<BatchOp>> batch_ops;
393405

394406
ceph_tid_t reintegration_reqid = 0;

src/mds/Locker.cc

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4529,8 +4529,7 @@ void Locker::issue_client_lease(CDentry *dn, CInode *in, const MDRequestRef& mdr
45294529
void Locker::revoke_client_leases(SimpleLock *lock)
45304530
{
45314531
CDentry *dn = static_cast<CDentry*>(lock->get_parent());
4532-
for (auto& p : dn->client_leases) {
4533-
ClientLease *l = &p.second;
4532+
for (ClientLease& l : dn->client_leases) {
45344533

45354534
ceph_assert(lock->get_type() == CEPH_LOCK_DN);
45364535

@@ -4539,8 +4538,8 @@ void Locker::revoke_client_leases(SimpleLock *lock)
45394538

45404539
// i should also revoke the dir ICONTENT lease, if they have it!
45414540
CInode *diri = dn->get_dir()->get_inode();
4542-
auto lease = make_message<MClientLease>(CEPH_MDS_LEASE_REVOKE, l->seq, mask, diri->ino(), diri->first, CEPH_NOSNAP, dn->get_name());
4543-
mds->send_message_client_counted(lease, l->session);
4541+
auto lease = make_message<MClientLease>(CEPH_MDS_LEASE_REVOKE, l.seq, mask, diri->ino(), diri->first, CEPH_NOSNAP, dn->get_name());
4542+
mds->send_message_client_counted(lease, l.session);
45444543
}
45454544
}
45464545

0 commit comments

Comments
 (0)