]> git.apps.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>
Tue, 5 Feb 2019 09:06:15 +0000 (17:06 +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)

 Conflicts:
src/mds/Capability.cc

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

index 0c89617aa7c4a6384c62d995238e375daa87b5e9..c834fc427e46c00ea7ddfa30b0edc2bf4efaee9b 100644 (file)
@@ -2816,7 +2816,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 5c50b59eb7add645cd80c3b09b9ba049104aee5d..98be60f079f4b5c21de86b4aedef740e93b36106 100644 (file)
@@ -152,6 +152,9 @@ 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
@@ -164,6 +167,36 @@ 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 (!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;
+}
+
 void Capability::encode(bufferlist& bl) const
 {
   ENCODE_START(2, 2, bl)
@@ -187,7 +220,7 @@ void Capability::decode(bufferlist::iterator &bl)
   ::decode(_revokes, bl);
   DECODE_FINISH(bl);
   
-  _calc_issued();
+  calc_issued();
 }
 
 void Capability::dump(Formatter *f) const
index af7ca015a4664948ef1486619b2b9ae9c4ef6ef1..4ff5b811fc852eb91f8c41e8d180eeeb882a4c65 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_CLIENTWRITEABLE  = (1<<4);
@@ -129,6 +130,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;
@@ -152,13 +155,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;
@@ -171,16 +169,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();
   }
@@ -193,10 +192,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();
       }
     }
   }
@@ -223,6 +224,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; }
@@ -235,11 +241,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();
     }
   }
 
@@ -248,11 +257,8 @@ public:
   client_t get_client() const;
 
   // caps this client wants to hold
-  int wanted() { return _wanted; }
-  void set_wanted(int w) {
-    _wanted = w;
-    //check_rdcaps_list();
-  }
+  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; }
@@ -283,7 +289,7 @@ public:
     client_follows = other.client_follows;
 
     // wanted
-    _wanted = _wanted | other.wanted;
+    set_wanted(wanted() | other.wanted);
     if (auth_cap)
       mseq = other.mseq;
   }
@@ -300,7 +306,7 @@ public:
     }
 
     // wanted
-    _wanted = _wanted | otherwanted;
+    set_wanted(wanted() | otherwanted);
   }
 
   void revoke() {
@@ -350,6 +356,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 eee382f4af7849033909b0610f5182c00fa91ef8..404c456d770237e9657206d0d4e90be75e81a49d 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) {