From: Yan, Zheng Date: Thu, 22 Nov 2018 09:28:15 +0000 (+0800) Subject: mds: put notable caps at the front of session's caps list X-Git-Tag: v14.1.0~293^2~5 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=cb6e7184458e64720ad83c266e5e393a80c32697;p=ceph.git 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" --- diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index 5821b7adad24..0bd1410fec87 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -3013,7 +3013,6 @@ Capability *CInode::add_client_cap(client_t client, Session *session, SnapRealm ceph_assert(ret.second == true); Capability *cap = &ret.first->second; - 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 4e88f0c8d544..21be39d6f4e1 100644 --- a/src/mds/Capability.cc +++ b/src/mds/Capability.cc @@ -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::const_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 44c8f98ce9a2..2081e055e1c4 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_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) diff --git a/src/mds/SessionMap.h b/src/mds/SessionMap.h index c5ae604f9a6e..870fb3e9ea49 100644 --- a/src/mds/SessionMap.h +++ b/src/mds/SessionMap.h @@ -271,7 +271,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) {