]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: put Capability in map container 22289/head
authorYan, Zheng <zyan@redhat.com>
Mon, 28 May 2018 02:55:55 +0000 (10:55 +0800)
committerYan, Zheng <zyan@redhat.com>
Tue, 29 May 2018 03:43:37 +0000 (11:43 +0800)
Simplifies memory management and reduces memory fragmentation

Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
src/mds/CInode.cc
src/mds/CInode.h
src/mds/Capability.h
src/mds/Locker.cc
src/mds/MDCache.cc
src/mds/Migrator.cc

index cd76392773801089b3b1699139ea237f3d98198a..2e93d1a21ee622867d9d8d22c6810e783a11d787 100644 (file)
@@ -210,16 +210,16 @@ ostream& operator<<(ostream& out, const CInode& in)
 
   if (!in.get_client_caps().empty()) {
     out << " caps={";
-    for (map<client_t,Capability*>::const_iterator it = in.get_client_caps().begin();
-         it != in.get_client_caps().end();
-         ++it) {
-      if (it != in.get_client_caps().begin()) out << ",";
-      out << it->first << "="
-         << ccap_string(it->second->pending());
-      if (it->second->issued() != it->second->pending())
-       out << "/" << ccap_string(it->second->issued());
-      out << "/" << ccap_string(it->second->wanted())
-         << "@" << it->second->get_last_sent();
+    bool first = true;
+    for (const auto &p : in.get_client_caps()) {
+      if (!first) out << ",";
+      out << p.first << "="
+         << ccap_string(p.second.pending());
+      if (p.second.issued() != p.second.pending())
+       out << "/" << ccap_string(p.second.issued());
+      out << "/" << ccap_string(p.second.wanted())
+         << "@" << p.second.get_last_sent();
+      first = false;
     }
     out << "}";
     if (in.get_loner() >= 0 || in.get_wanted_loner() >= 0) {
@@ -2836,17 +2836,16 @@ client_t CInode::calc_ideal_loner()
   
   int n = 0;
   client_t loner = -1;
-  for (map<client_t,Capability*>::iterator it = client_caps.begin();
-       it != client_caps.end();
-       ++it) 
-    if (!it->second->is_stale() &&
-       ((it->second->wanted() & (CEPH_CAP_ANY_WR|CEPH_CAP_FILE_WR|CEPH_CAP_FILE_RD)) ||
+  for (const auto &p : client_caps) {
+    if (!p.second.is_stale() &&
+       ((p.second.wanted() & (CEPH_CAP_ANY_WR|CEPH_CAP_FILE_WR|CEPH_CAP_FILE_RD)) ||
         (inode.is_dir() && !has_subtree_root_dirfrag()))) {
       if (n)
        return -1;
       n++;
-      loner = it->first;
+      loner = p.first;
     }
+  }
   return loner;
 }
 
@@ -2998,26 +2997,27 @@ Capability *CInode::add_client_cap(client_t client, Session *session, SnapRealm
     if (parent)
       parent->dir->adjust_num_inodes_with_caps(1);
   }
-  
-  Capability *cap = new Capability(this, ++mdcache->last_cap_id, client);
-  assert(client_caps.count(client) == 0);
-  client_caps[client] = cap;
+
+  uint64_t cap_id = ++mdcache->last_cap_id;
+  auto ret = client_caps.emplace(std::piecewise_construct, std::forward_as_tuple(client),
+                                 std::forward_as_tuple(this, cap_id, client));
+  assert(ret.second == true);
+  Capability *cap = &ret.first->second;
 
   session->add_cap(cap);
   if (session->is_stale())
     cap->mark_stale();
-  
   cap->client_follows = first-1;
-  
   containing_realm->add_cap(client, cap);
-  
+
   return cap;
 }
 
 void CInode::remove_client_cap(client_t client)
 {
-  assert(client_caps.count(client) == 1);
-  Capability *cap = client_caps[client];
+  auto it = client_caps.find(client);
+  assert(it != client_caps.end());
+  Capability *cap = &it->second;
   
   cap->item_session_caps.remove_myself();
   cap->item_revoking_caps.remove_myself();
@@ -3030,8 +3030,7 @@ void CInode::remove_client_cap(client_t client)
   if (cap->wanted())
     adjust_num_caps_wanted(-1);
 
-  delete cap;
-  client_caps.erase(client);
+  client_caps.erase(it);
   if (client_caps.empty()) {
     dout(10) << __func__ << " last cap, leaving realm " << *containing_realm << dendl;
     put(PIN_CAPS);
@@ -3056,11 +3055,9 @@ void CInode::move_to_realm(SnapRealm *realm)
 {
   dout(10) << __func__ << " joining realm " << *realm
           << ", leaving realm " << *containing_realm << dendl;
-  for (map<client_t,Capability*>::iterator q = client_caps.begin();
-       q != client_caps.end();
-       ++q) {
-    containing_realm->remove_cap(q->first, q->second);
-    realm->add_cap(q->first, q->second);
+  for (auto& p : client_caps) {
+    containing_realm->remove_cap(p.first, &p.second);
+    realm->add_cap(p.first, &p.second);
   }
   item_caps.remove_myself();
   realm->inodes_with_caps.push_back(&item_caps);
@@ -3098,10 +3095,8 @@ void CInode::clear_client_caps_after_export()
 
 void CInode::export_client_caps(map<client_t,Capability::Export>& cl)
 {
-  for (map<client_t,Capability*>::iterator it = client_caps.begin();
-       it != client_caps.end();
-       ++it) {
-    cl[it->first] = it->second->make_export();
+  for (const auto &p : client_caps) {
+    cl[p.first] = p.second.make_export();
   }
 }
 
@@ -3190,16 +3185,14 @@ int CInode::get_caps_issued(int *ploner, int *pother, int *pxlocker,
     loner_cap = -1;
   }
 
-  for (map<client_t,Capability*>::const_iterator it = client_caps.begin();
-       it != client_caps.end();
-       ++it) {
-    int i = it->second->issued();
+  for (const auto &p : client_caps) {
+    int i = p.second.issued();
     c |= i;
-    if (it->first == loner_cap)
+    if (p.first == loner_cap)
       loner |= i;
     else
       other |= i;
-    xlocker |= get_xlocker_mask(it->first) & i;
+    xlocker |= get_xlocker_mask(p.first) & i;
   }
   if (ploner) *ploner = (loner >> shift) & mask;
   if (pother) *pother = (other >> shift) & mask;
@@ -3209,11 +3202,10 @@ int CInode::get_caps_issued(int *ploner, int *pother, int *pxlocker,
 
 bool CInode::is_any_caps_wanted() const
 {
-  for (map<client_t,Capability*>::const_iterator it = client_caps.begin();
-       it != client_caps.end();
-       ++it)
-    if (it->second->wanted())
+  for (const auto &p : client_caps) {
+    if (p.second.wanted())
       return true;
+  }
   return false;
 }
 
@@ -3221,13 +3213,11 @@ int CInode::get_caps_wanted(int *ploner, int *pother, int shift, int mask) const
 {
   int w = 0;
   int loner = 0, other = 0;
-  for (map<client_t,Capability*>::const_iterator it = client_caps.begin();
-       it != client_caps.end();
-       ++it) {
-    if (!it->second->is_stale()) {
-      int t = it->second->wanted();
+  for (const auto &p : client_caps) {
+    if (!p.second.is_stale()) {
+      int t = p.second.wanted();
       w |= t;
-      if (it->first == loner_cap)
+      if (p.first == loner_cap)
        loner |= t;
       else
        other |= t;     
@@ -4511,7 +4501,7 @@ void CInode::dump(Formatter *f, int flags) const
     f->open_array_section("client_caps");
     for (const auto &p : client_caps) {
       auto &client = p.first;
-      auto &cap = p.second;
+      auto cap = &p.second;
       f->open_object_section("client_cap");
       f->dump_int("client_id", client.v);
       f->dump_string("pending", ccap_string(cap->pending()));
index 99308d1b6cef892d0eaa9ae611c2e9e1b424428e..551ac640122cf3bf960055904f3a2ae0ea01c409 100644 (file)
@@ -581,8 +581,8 @@ public:
   // -- distributed state --
 protected:
   // file capabilities
-  using cap_map = mempool::mds_co::map<client_t, Capability*>;
-  cap_map client_caps;         // client -> caps
+  using mempool_cap_map = mempool::mds_co::map<client_t, Capability>;
+  mempool_cap_map client_caps;         // client -> caps
   mempool::mds_co::compact_map<int32_t, int32_t>      mds_caps_wanted;     // [auth] mds -> caps wanted
   int replica_caps_wanted = 0; // [replica] what i've requested from auth
   int num_caps_wanted = 0;
@@ -975,7 +975,7 @@ public:
   int count_nonstale_caps() {
     int n = 0;
     for (const auto &p : client_caps) {
-      if (!p.second->is_stale())
+      if (!p.second.is_stale())
        n++;
     }
     return n;
@@ -983,7 +983,7 @@ public:
   bool multiple_nonstale_caps() {
     int n = 0;
     for (const auto &p : client_caps) {
-      if (!p.second->is_stale()) {
+      if (!p.second.is_stale()) {
        if (n)
          return true;
        n++;
@@ -999,17 +999,17 @@ public:
   void set_mds_caps_wanted(mempool::mds_co::compact_map<int32_t,int32_t>& m);
   void set_mds_caps_wanted(mds_rank_t mds, int32_t wanted);
 
-  const cap_map& get_client_caps() const { return client_caps; }
+  const mempool_cap_map& get_client_caps() const { return client_caps; }
   Capability *get_client_cap(client_t client) {
     auto client_caps_entry = client_caps.find(client);
     if (client_caps_entry != client_caps.end())
-      return client_caps_entry->second;
+      return &client_caps_entry->second;
     return 0;
   }
   int get_client_cap_pending(client_t client) const {
     auto client_caps_entry = client_caps.find(client);
     if (client_caps_entry != client_caps.end()) {
-      return client_caps_entry->second->pending();
+      return client_caps_entry->second.pending();
     } else {
       return 0;
     }
index 690dd1ebdc47a3e7f21abdb6e452f994060f3b18..a2a5d5b9feae185ad363c211832e3730d339d39a 100644 (file)
@@ -135,9 +135,9 @@ public:
 
   const Capability& operator=(const Capability& other) = delete;
 
-  int pending() { return _pending; }
-  int issued() { return _issued; }
-  bool is_null() { return !_pending && _revokes.empty(); }
+  int pending() const { return _pending; }
+  int issued() const { return _issued; }
+  bool is_null() const { return !_pending && _revokes.empty(); }
 
   ceph_seq_t issue(unsigned c) {
     if (_pending & ~c) {
@@ -216,52 +216,52 @@ public:
       }
     }
   }
-  ceph_seq_t get_mseq() { return mseq; }
+  ceph_seq_t get_mseq() const { return mseq; }
   void inc_mseq() { mseq++; }
 
-  ceph_seq_t get_last_sent() { return last_sent; }
-  utime_t get_last_issue_stamp() { return last_issue_stamp; }
-  utime_t get_last_revoke_stamp() { return last_revoke_stamp; }
+  ceph_seq_t get_last_sent() const { return last_sent; }
+  utime_t get_last_issue_stamp() const { return last_issue_stamp; }
+  utime_t get_last_revoke_stamp() const { return last_revoke_stamp; }
 
   void set_last_issue() { last_issue = last_sent; }
   void set_last_issue_stamp(utime_t t) { last_issue_stamp = t; }
   void set_last_revoke_stamp(utime_t t) { last_revoke_stamp = t; }
   void reset_num_revoke_warnings() { num_revoke_warnings = 0; }
   void inc_num_revoke_warnings() { ++num_revoke_warnings; }
-  unsigned get_num_revoke_warnings() { return num_revoke_warnings; }
+  unsigned get_num_revoke_warnings() const { return num_revoke_warnings; }
 
   void set_cap_id(uint64_t i) { cap_id = i; }
-  uint64_t get_cap_id() { return cap_id; }
+  uint64_t get_cap_id() const { return cap_id; }
 
   //ceph_seq_t get_last_issue() { return last_issue; }
 
-  bool is_suppress() { return suppress > 0; }
+  bool is_suppress() const { return suppress > 0; }
   void inc_suppress() { suppress++; }
   void dec_suppress() { suppress--; }
 
-  bool is_stale() { return state & STATE_STALE; }
+  bool is_stale() const { return state & STATE_STALE; }
   void mark_stale() { state |= STATE_STALE; }
   void clear_stale() { state &= ~STATE_STALE; }
-  bool is_new() { return state & STATE_NEW; }
+  bool is_new() const { return state & STATE_NEW; }
   void mark_new() { state |= STATE_NEW; }
   void clear_new() { state &= ~STATE_NEW; }
-  bool is_importing() { return state & STATE_IMPORTING; }
+  bool is_importing() const { return state & STATE_IMPORTING; }
   void mark_importing() { state |= STATE_IMPORTING; }
   void clear_importing() { state &= ~STATE_IMPORTING; }
-  bool need_snapflush() { return state & STATE_NEEDSNAPFLUSH; }
+  bool need_snapflush() const { return state & STATE_NEEDSNAPFLUSH; }
   void mark_needsnapflush() { state |= STATE_NEEDSNAPFLUSH; }
   void clear_needsnapflush() { state &= ~STATE_NEEDSNAPFLUSH; }
 
-  CInode *get_inode() { return inode; }
+  CInode *get_inode() const { return inode; }
   client_t get_client() const { return client; }
 
   // caps this client wants to hold
-  int wanted() { return _wanted; }
+  int wanted() const { return _wanted; }
   void set_wanted(int w);
 
   void inc_last_seq() { last_sent++; }
-  ceph_seq_t get_last_seq() { return last_sent; }
-  ceph_seq_t get_last_issue() { return last_issue; }
+  ceph_seq_t get_last_seq() const { return last_sent; }
+  ceph_seq_t get_last_issue() const { return last_issue; }
 
   void reset_seq() {
     last_sent = 0;
@@ -269,7 +269,7 @@ public:
   }
   
   // -- exports --
-  Export make_export() {
+  Export make_export() const {
     return Export(cap_id, _wanted, issued(), pending(), client_follows, last_sent, mseq+1, last_issue_stamp);
   }
   void merge(const Export& other, bool auth_cap) {
index 798215defa25e48286258339dcd7ad9b2d00a98c..82e20ae3fe1d58369fef9ef20524189d575ee2ef 100644 (file)
@@ -2005,13 +2005,13 @@ bool Locker::issue_caps(CInode *in, Capability *only_cap)
   int nissued = 0;        
 
   // client caps
-  map<client_t, Capability*>::iterator it;
+  map<client_t, Capability>::iterator it;
   if (only_cap)
     it = in->client_caps.find(only_cap->get_client());
   else
     it = in->client_caps.begin();
   for (; it != in->client_caps.end(); ++it) {
-    Capability *cap = it->second;
+    Capability *cap = &it->second;
     if (cap->is_stale())
       continue;
 
@@ -2110,10 +2110,8 @@ void Locker::issue_truncate(CInode *in)
 {
   dout(7) << "issue_truncate on " << *in << dendl;
   
-  for (map<client_t, Capability*>::iterator it = in->client_caps.begin();
-       it != in->client_caps.end();
-       ++it) {
-    Capability *cap = it->second;
+  for (auto &p : in->client_caps) {
+    Capability *cap = &p.second;
     MClientCaps *m = new MClientCaps(CEPH_CAP_OP_TRUNC,
                                     in->ino(),
                                     in->find_snaprealm()->inode->ino(),
@@ -2122,7 +2120,7 @@ void Locker::issue_truncate(CInode *in)
                                     cap->get_mseq(),
                                      mds->get_osd_epoch_barrier());
     in->encode_cap_message(m, cap);                         
-    mds->send_message_client_counted(m, it->first);
+    mds->send_message_client_counted(m, p.first);
   }
 
   // should we increase max_size?
@@ -2328,14 +2326,12 @@ void Locker::calc_new_client_ranges(CInode *in, uint64_t size,
 
   // increase ranges as appropriate.
   // shrink to 0 if no WR|BUFFER caps issued.
-  for (map<client_t,Capability*>::iterator p = in->client_caps.begin();
-       p != in->client_caps.end();
-       ++p) {
-    if ((p->second->issued() | p->second->wanted()) & (CEPH_CAP_FILE_WR|CEPH_CAP_FILE_BUFFER)) {
-      client_writeable_range_t& nr = (*new_ranges)[p->first];
+  for (const auto &p : in->get_client_caps()) {
+    if ((p.second.issued() | p.second.wanted()) & (CEPH_CAP_FILE_WR|CEPH_CAP_FILE_BUFFER)) {
+      client_writeable_range_t& nr = (*new_ranges)[p.first];
       nr.range.first = 0;
-      if (latest->client_ranges.count(p->first)) {
-       client_writeable_range_t& oldr = latest->client_ranges[p->first];
+      if (latest->client_ranges.count(p.first)) {
+       client_writeable_range_t& oldr = latest->client_ranges[p.first];
        if (ms > oldr.range.last)
          *max_increased = true;
        nr.range.last = std::max(ms, oldr.range.last);
@@ -2481,14 +2477,14 @@ void Locker::share_inode_max_size(CInode *in, Capability *only_cap)
    * the cap later.
    */
   dout(10) << "share_inode_max_size on " << *in << dendl;
-  map<client_t, Capability*>::iterator it;
+  map<client_t, Capability>::iterator it;
   if (only_cap)
     it = in->client_caps.find(only_cap->get_client());
   else
     it = in->client_caps.begin();
   for (; it != in->client_caps.end(); ++it) {
     const client_t client = it->first;
-    Capability *cap = it->second;
+    Capability *cap = &it->second;
     if (cap->is_suppress())
       continue;
     if (cap->pending() & (CEPH_CAP_FILE_WR|CEPH_CAP_FILE_BUFFER)) {
index 810edeb5d1331b17d1cc9cc6e6c0110a974f2e76..03d43d51cbedb441524f3ae21c7b8e305f14abc7 100644 (file)
@@ -1559,7 +1559,7 @@ CInode *MDCache::cow_inode(CInode *in, snapid_t last)
     // clone caps?
     for (auto &p : in->client_caps) {
       client_t client = p.first;
-      Capability *cap = p.second;
+      Capability *cap = &p.second;
       int issued = cap->need_snapflush() ? CEPH_CAP_ANY_WR : cap->issued();
       if ((issued & CEPH_CAP_ANY_WR) &&
          cap->client_follows < last) {
@@ -2017,17 +2017,15 @@ void MDCache::broadcast_quota_to_client(CInode *in, client_t exclude_ct)
   if (!in->get_projected_srnode())
     mds->server->create_quota_realm(in);
 
-  for (map<client_t,Capability*>::iterator it = in->client_caps.begin();
-       it != in->client_caps.end();
-       ++it) {
-    Session *session = mds->get_session(it->first);
+  for (auto &p : in->client_caps) {
+    Session *session = mds->get_session(p.first);
     if (!session || !session->connection ||
         !session->connection->has_feature(CEPH_FEATURE_MDS_QUOTA))
       continue;
 
-    Capability *cap = it->second;
+    Capability *cap = &p.second;
 
-    if (exclude_ct >= 0 && exclude_ct != it->first)
+    if (exclude_ct >= 0 && exclude_ct != p.first)
       goto update;
 
     if (cap->last_rbytes == i->rstat.rbytes &&
index d8ac9154a345c5d2d449bb6cedb381f0874b94c5..40b6ca8b2ccaac3b201c060040aea89a92f27f7a 100644 (file)
@@ -1256,11 +1256,9 @@ void Migrator::check_export_size(CDir *dir, export_state_t& stat, set<client_t>&
          }
        }
       }
-      for (map<client_t, Capability*>::iterator q = in->client_caps.begin();
-          q != in->client_caps.end();
-          ++q) {
+      for (const auto &q : in->get_client_caps()) {
        approx_size += cap_size;
-       client_set.insert(q->first);
+       client_set.insert(q.first);
       }
     }
 
@@ -1288,10 +1286,9 @@ void Migrator::check_export_size(CDir *dir, export_state_t& stat, set<client_t>&
 
 void Migrator::get_export_client_set(CInode *in, set<client_t>& client_set)
 {
-  for (map<client_t, Capability*>::iterator q = in->client_caps.begin();
-      q != in->client_caps.end();
-      ++q)
-    client_set.insert(q->first);
+  for (const auto &p : in->get_client_caps()) {
+    client_set.insert(p.first);
+  }
 }
 
 /* This function DOES put the passed message before returning*/
@@ -1494,10 +1491,9 @@ void Migrator::encode_export_inode_caps(CInode *in, bool auth_cap, bufferlist& b
   }
 
   // make note of clients named by exported capabilities
-  for (map<client_t, Capability*>::iterator it = in->client_caps.begin();
-       it != in->client_caps.end();
-       ++it) 
-    exported_client_map[it->first] = mds->sessionmap.get_inst(entity_name_t::CLIENT(it->first.v));
+  for (const auto &p : in->get_client_caps()) {
+    exported_client_map[p.first] = mds->sessionmap.get_inst(entity_name_t::CLIENT(p.first.v));
+  }
 }
 
 void Migrator::finish_export_inode_caps(CInode *in, mds_rank_t peer,
@@ -1509,20 +1505,18 @@ void Migrator::finish_export_inode_caps(CInode *in, mds_rank_t peer,
   in->put(CInode::PIN_EXPORTINGCAPS);
 
   // tell (all) clients about migrating caps.. 
-  for (map<client_t, Capability*>::iterator it = in->client_caps.begin();
-       it != in->client_caps.end();
-       ++it) {
-    Capability *cap = it->second;
-    dout(7) << "finish_export_inode_caps telling client." << it->first
+  for (const auto &p : in->get_client_caps()) {
+    const Capability *cap = &p.second;
+    dout(7) << "finish_export_inode_caps telling client." << p.first
            << " exported caps on " << *in << dendl;
     MClientCaps *m = new MClientCaps(CEPH_CAP_OP_EXPORT, in->ino(), 0,
                                     cap->get_cap_id(), cap->get_mseq(), mds->get_osd_epoch_barrier());
 
-    map<client_t,Capability::Import>::iterator q = peer_imported.find(it->first);
+    map<client_t,Capability::Import>::iterator q = peer_imported.find(p.first);
     assert(q != peer_imported.end());
     m->set_cap_peer(q->second.cap_id, q->second.issue_seq, q->second.mseq,
                    (q->second.cap_id > 0 ? peer : -1), 0);
-    mds->send_message_client_counted(m, it->first);
+    mds->send_message_client_counted(m, p.first);
   }
   in->clear_client_caps_after_export();
   mds->locker->eval(in, CEPH_CAP_LOCKS);
@@ -1871,8 +1865,8 @@ void Migrator::export_reverse(CDir *dir, export_state_t& stat)
   // revoke/resume stale caps
   for (auto in : to_eval) {
     bool need_issue = false;
-    for (auto& p : in->get_client_caps()) {
-      Capability *cap = p.second;
+    for (auto &p : in->client_caps) {
+      Capability *cap = &p.second;
       if (cap->is_stale()) {
        mds->locker->revoke_stale_caps(cap);
       } else {