]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: put notable caps at the front of session's caps list
authorYan, Zheng <zyan@redhat.com>
Thu, 22 Nov 2018 09:28:15 +0000 (17:28 +0800)
committerYan, Zheng <zyan@redhat.com>
Mon, 21 Oct 2019 02:52:21 +0000 (10:52 +0800)
Notable Capabilities are ones that are being revoked, ones that
have writeable ranges and ones that want exclusive caps or want
file read/write.

Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
(cherry picked from commit cb6e7184458e64720ad83c266e5e393a80c32697)

src/mds/CInode.cc
src/mds/Capability.cc
src/mds/Capability.h
src/mds/SessionMap.h

index b648b6d5001b53c1af364d429b5c5f755346e293..ce4ae83fafee54b6778152a01195dd0b14f4f20f 100644 (file)
@@ -3011,7 +3011,6 @@ Capability *CInode::add_client_cap(client_t client, Session *session, SnapRealm
   assert(client_caps.count(client) == 0);
   client_caps[client] = cap;
 
-  session->add_cap(cap);
   cap->client_follows = first-1;
   
   containing_realm->add_cap(client, cap);
index 1624de325f89655bf95241d2990801fdaec33ca6..79b7b371af26bc2f8b3846102cad949edec13d0a 100644 (file)
@@ -153,6 +153,8 @@ Capability::Capability(CInode *i, Session *s, uint64_t id) :
   _pending(0), _issued(0), last_sent(0), last_issue(0), mseq(0),
   suppress(0), state(0)
 {
+  if (session)
+    session->touch_cap_bottom(this);
 }
 
 client_t Capability::get_client() const
@@ -165,13 +167,37 @@ bool Capability::is_stale() const
   return session ? session->is_stale() : false;
 }
 
+void Capability::mark_notable()
+{
+  state |= STATE_NOTABLE;
+  session->touch_cap(this);
+}
+
+void Capability::maybe_clear_notable()
+{
+  if ((_issued == _pending) &&
+      !is_clientwriteable() &&
+      !is_wanted_notable(_wanted)) {
+    ceph_assert(is_notable());
+    state &= ~STATE_NOTABLE;
+    session->touch_cap_bottom(this);
+  }
+}
+
 void Capability::set_wanted(int w) {
   CInode *in = get_inode();
   if (in) {
-    if (!_wanted && w)
+    if (!_wanted && w) {
       in->adjust_num_caps_wanted(1);
-    else if (_wanted && !w)
+    } else if (_wanted && !w) {
       in->adjust_num_caps_wanted(-1);
+    }
+    if (!is_wanted_notable(_wanted) && is_wanted_notable(w)) {
+      if (!is_notable())
+       mark_notable();
+    } else if (is_wanted_notable(_wanted) && !is_wanted_notable(w)) {
+      maybe_clear_notable();
+    }
   }
   _wanted = w;
 }
@@ -201,7 +227,7 @@ void Capability::decode(bufferlist::iterator &bl)
   decode(_revokes, bl);
   DECODE_FINISH(bl);
   
-  _calc_issued();
+  calc_issued();
 }
 
 void Capability::dump(Formatter *f) const
index edb6bb67aa4715e24e1cd6558f6df00a95b8f471..71492c783dcc86c139772da3c5967d49b38b2551 100644 (file)
@@ -110,6 +110,7 @@ public:
     static void generate_test_instances(list<revoke_info*>& ls);
   };
 
+  const static unsigned STATE_NOTABLE          = (1<<0);
   const static unsigned STATE_NEW              = (1<<1);
   const static unsigned STATE_IMPORTING                = (1<<2);
   const static unsigned STATE_NEEDSNAPFLUSH    = (1<<3);
@@ -130,6 +131,8 @@ public:
       _revokes.emplace_back(_pending, last_sent, last_issue);
       _pending = c;
       _issued |= c;
+      if (!is_notable())
+       mark_notable();
     } else if (~_pending & c) {
       // adding bits only.  remove obsolete revocations?
       _pending |= c;
@@ -153,13 +156,8 @@ public:
     inc_last_seq();
     return last_sent;
   }
-  void _calc_issued() {
-    _issued = _pending;
-    for (const auto &r : _revokes) {
-      _issued |= r.before;
-    }
-  }
   void confirm_receipt(ceph_seq_t seq, unsigned caps) {
+    bool was_revoking = (_issued & ~_pending);
     if (seq == last_sent) {
       _revokes.clear();
       _issued = caps;
@@ -172,16 +170,17 @@ public:
       if (!_revokes.empty()) {
        if (_revokes.front().seq == seq)
          _revokes.begin()->before = caps;
-       _calc_issued();
+       calc_issued();
       } else {
        // seq < last_sent
        _issued = caps | _pending;
       }
     }
 
-    if (_issued == _pending) {
+    if (was_revoking && _issued == _pending) {
       item_revoking_caps.remove_myself();
       item_client_revoking_caps.remove_myself();
+      maybe_clear_notable();
     }
     //check_rdcaps_list();
   }
@@ -194,10 +193,12 @@ public:
       changed = true;
     }
     if (changed) {
-      _calc_issued();
-      if (_issued == _pending) {
+      bool was_revoking = (_issued & ~_pending);
+      calc_issued();
+      if (was_revoking && _issued == _pending) {
        item_revoking_caps.remove_myself();
        item_client_revoking_caps.remove_myself();
+       maybe_clear_notable();
       }
     }
   }
@@ -224,6 +225,11 @@ public:
   void inc_suppress() { suppress++; }
   void dec_suppress() { suppress--; }
 
+  static bool is_wanted_notable(int wanted) {
+    return wanted & (CEPH_CAP_ANY_WR|CEPH_CAP_FILE_WR|CEPH_CAP_FILE_RD);
+  }
+  bool is_notable() const { return state & STATE_NOTABLE; }
+
   bool is_stale() const;
   bool is_new() const { return state & STATE_NEW; }
   void mark_new() { state |= STATE_NEW; }
@@ -239,11 +245,14 @@ public:
   void mark_clientwriteable() {
     if (!is_clientwriteable()) {
       state |= STATE_CLIENTWRITEABLE;
+      if (!is_notable())
+       mark_notable();
     }
   }
   void clear_clientwriteable() {
     if (is_clientwriteable()) {
       state &= ~STATE_CLIENTWRITEABLE;
+      maybe_clear_notable();
     }
   }
 
@@ -351,6 +360,16 @@ private:
 
   int suppress;
   unsigned state;
+
+  void calc_issued() {
+    _issued = _pending;
+    for (const auto &r : _revokes) {
+      _issued |= r.before;
+    }
+  }
+
+  void mark_notable();
+  void maybe_clear_notable();
 };
 
 WRITE_CLASS_ENCODER(Capability::Export)
index 8d020a973c21b448ac241a53a49900bdf7ef4450..391b51c7754943bc1229f513aa8ed8b5a996333d 100644 (file)
@@ -265,7 +265,10 @@ public:
     }
   }
 
-  void add_cap(Capability *cap) {
+  void touch_cap(Capability *cap) {
+    caps.push_front(&cap->item_session_caps);
+  }
+  void touch_cap_bottom(Capability *cap) {
     caps.push_back(&cap->item_session_caps);
   }
   void touch_lease(ClientLease *r) {