From 066ef3f33eafd43ea50c48ef8f0bddf51ac0c252 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Thu, 22 Nov 2018 17:28:15 +0800 Subject: [PATCH] mds: put notable caps at the front of session's caps list 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" (cherry picked from commit cb6e7184458e64720ad83c266e5e393a80c32697) Conflicts: src/mds/Capability.cc --- src/mds/CInode.cc | 1 - src/mds/Capability.cc | 35 +++++++++++++++++++++++++++++- src/mds/Capability.h | 50 ++++++++++++++++++++++++++++--------------- src/mds/SessionMap.h | 5 ++++- 4 files changed, 71 insertions(+), 20 deletions(-) diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index 0c89617aa7c4a..c834fc427e46c 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -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); diff --git a/src/mds/Capability.cc b/src/mds/Capability.cc index 5c50b59eb7add..98be60f079f4b 100644 --- a/src/mds/Capability.cc +++ b/src/mds/Capability.cc @@ -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 diff --git a/src/mds/Capability.h b/src/mds/Capability.h index af7ca015a4664..4ff5b811fc852 100644 --- a/src/mds/Capability.h +++ b/src/mds/Capability.h @@ -110,6 +110,7 @@ public: static void generate_test_instances(list& 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) diff --git a/src/mds/SessionMap.h b/src/mds/SessionMap.h index eee382f4af784..404c456d77023 100644 --- a/src/mds/SessionMap.h +++ b/src/mds/SessionMap.h @@ -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) { -- 2.39.5