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: v13.2.7~27^2~10 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=b92d5a796829e0424ba36aee053147591640caa0;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" (cherry picked from commit cb6e7184458e64720ad83c266e5e393a80c32697) --- diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index b648b6d5001b..ce4ae83fafee 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -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); diff --git a/src/mds/Capability.cc b/src/mds/Capability.cc index 1624de325f89..79b7b371af26 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::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 edb6bb67aa47..71492c783dcc 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 8d020a973c21..391b51c77549 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) {