}
-ClientLease *CDentry::add_client_lease(client_t c, Session *session)
-{
- ClientLease *l;
- if (client_lease_map.count(c))
- l = client_lease_map[c];
- else {
- dout(20) << __func__ << " client." << c << " on " << lock << dendl;
- if (client_lease_map.empty()) {
+client_t ClientLease::get_client() const
+{
+ return session->get_client();
+}
+
+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) {
+ dout(20) << __func__ << " client." << client << " on " << lock << dendl;
+ if (client_leases.size() == 1) {
get(PIN_CLIENTLEASE);
lock.get_client_lease();
}
- l = client_lease_map[c] = new ClientLease(c, this);
l->seq = ++session->lease_seq;
-
}
-
return l;
}
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->client << " on " << lock << dendl;
-
- client_lease_map.erase(l->client);
l->item_lease.remove_myself();
l->item_session_lease.remove_myself();
- delete l;
+ client_leases.erase(client);
- if (client_lease_map.empty()) {
+ if (client_leases.empty()) {
gather = !lock.is_stable();
lock.put_client_lease();
put(PIN_CLIENTLEASE);
void CDentry::remove_client_leases(Locker *locker)
{
- while (!client_lease_map.empty())
- remove_client_lease(client_lease_map.begin()->second, locker);
+ while (!client_leases.empty())
+ remove_client_lease(&client_leases.begin()->second, locker);
}
void CDentry::_put()
#include "ScrubHeader.h"
class CInode;
+class CDentry;
class CDir;
class Locker;
class CDentry;
class LogSegment;
-
class Session;
+struct ClientLease {
+ ClientLease(CDentry *p, Session *s) :
+ parent(p), session(s),
+ item_session_lease(this),
+ item_lease(this) { }
+ ClientLease() = delete;
+ client_t get_client() const;
+
+ CDentry *parent;
+ Session *session;
+
+ ceph_seq_t seq = 0;
+ utime_t ttl;
+ xlist<ClientLease*>::item item_session_lease; // per-session list
+ xlist<ClientLease*>::item item_lease; // global list
+};
+
// define an ordering
bool operator<(const CDentry& l, const CDentry& r);
// replicas (on clients)
bool is_any_leases() const {
- return !client_lease_map.empty();
+ return !client_leases.empty();
}
const ClientLease *get_client_lease(client_t c) const {
- if (client_lease_map.count(c))
- return client_lease_map.find(c)->second;
- return 0;
+ auto it = client_leases.find(c);
+ if (it != client_leases.end())
+ return &it->second;
+ return nullptr;
}
ClientLease *get_client_lease(client_t c) {
- if (client_lease_map.count(c))
- return client_lease_map.find(c)->second;
- return 0;
+ auto it = client_leases.find(c);
+ if (it != client_leases.end())
+ return &it->second;
+ return nullptr;
}
bool have_client_lease(client_t c) const {
- const ClientLease *l = get_client_lease(c);
- if (l)
- return true;
- else
- return false;
+ return client_leases.count(c);
}
- ClientLease *add_client_lease(client_t c, Session *session);
+ ClientLease *add_client_lease(Session *session);
void remove_client_lease(ClientLease *r, Locker *locker); // returns remaining mask (if any), and kicks locker eval_gathers
void remove_client_leases(Locker *locker);
SimpleLock lock; // FIXME referenced containers not in mempool
LocalLockC versionlock; // FIXME referenced containers not in mempool
- mempool::mds_co::map<client_t,ClientLease*> client_lease_map;
+ mempool::mds_co::map<client_t, ClientLease> client_leases;
std::map<int, std::unique_ptr<BatchOp>> batch_ops;
ceph_tid_t reintegration_reqid = 0;
dout(12) << __func__ << " " << *dn << dendl;
// there should be no client leases at this point!
- ceph_assert(dn->client_lease_map.empty());
+ ceph_assert(dn->client_leases.empty());
if (state_test(CDir::STATE_DNPINNEDFRAG)) {
dn->put(CDentry::PIN_FRAGMENTING);
ceph_assert(!in);
}
// issue a dentry lease
- ClientLease *l = dn->add_client_lease(client, session);
+ ClientLease *l = dn->add_client_lease(session);
session->touch_lease(l);
int pool = 1; // fixme.. do something smart!
void Locker::revoke_client_leases(SimpleLock *lock)
{
CDentry *dn = static_cast<CDentry*>(lock->get_parent());
- for (map<client_t, ClientLease*>::iterator p = dn->client_lease_map.begin();
- p != dn->client_lease_map.end();
- ++p) {
- ClientLease *l = p->second;
-
+ for (auto& p : dn->client_leases) {
+ ClientLease *l = &p.second;
+
ceph_assert(lock->get_type() == CEPH_LOCK_DN);
CDentry *dn = static_cast<CDentry*>(lock->get_parent());
// 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->client);
+ mds->send_message_client_counted(lease, l->session);
}
}
ClientLease *r = list.front();
if (r->ttl > now) break;
CDentry *dn = static_cast<CDentry*>(r->parent);
- dout(10) << " expiring client." << r->client << " lease of " << *dn << dendl;
+ dout(10) << " expiring client." << r->get_client() << " lease of " << *dn << dendl;
dn->remove_client_lease(r, mds->locker);
}
auto after = list.size();
//#define MDS_AUTHPIN_SET // define me for debugging auth pin leaks
//#define MDS_VERIFY_FRAGSTAT // do (slow) sanity checking on frags
-/*
- * for metadata leases to clients
- */
class MLock;
class SimpleLock;
class MDSCacheObject;
class Formatter;
}
-struct ClientLease {
- ClientLease(client_t c, MDSCacheObject *p) :
- client(c), parent(p),
- item_session_lease(this),
- item_lease(this) { }
- ClientLease() = delete;
-
- client_t client;
- MDSCacheObject *parent;
-
- ceph_seq_t seq = 0;
- utime_t ttl;
- xlist<ClientLease*>::item item_session_lease; // per-session list
- xlist<ClientLease*>::item item_lease; // global list
-};
-
// print hack
struct mdsco_db_line_prefix {
explicit mdsco_db_line_prefix(MDSCacheObject *o) : object(o) {}