From: Yan, Zheng Date: Thu, 22 Nov 2018 07:02:36 +0000 (+0800) Subject: client: skip updating 'wanted' caps if caps are already issued X-Git-Tag: v14.1.0~293^2~8 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=d20b260ecf3f323c87ad1e6865f87e2381444546;p=ceph.git client: skip updating 'wanted' caps if caps are already issued When reading cached inode that already has Fscr caps, this can avoid two cap messages (one updats 'wanted' caps, one clears 'wanted' caps). Signed-off-by: "Yan, Zheng" --- diff --git a/src/client/Client.cc b/src/client/Client.cc index d8dbb6423d26..35f60289148b 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -3553,9 +3553,8 @@ void Client::check_caps(Inode *in, unsigned flags) if (!revoking && unmounting && (cap_used == 0)) goto ack; - if (wanted == cap.wanted && // mds knows what we want. - ((cap.issued & ~retain) == 0) &&// and we don't have anything we wouldn't like - !in->dirty_caps) // and we have no dirty caps + if ((cap.issued & ~retain) == 0 && // and we don't have anything we wouldn't like + !in->dirty_caps) // and we have no dirty caps continue; if (!(flags & CHECK_CAPS_NODELAY)) { @@ -5141,6 +5140,7 @@ void Client::handle_cap_grant(MetaSession *session, Inode *in, Cap *cap, MClient const int old_caps = cap->issued; const int new_caps = m->get_caps(); + const bool was_stale = session->cap_gen > cap->gen; ldout(cct, 5) << __func__ << " on in " << m->get_ino() << " mds." << mds << " seq " << m->get_seq() << " caps now " << ccap_string(new_caps) @@ -5214,8 +5214,17 @@ void Client::handle_cap_grant(MetaSession *session, Inode *in, Cap *cap, MClient } bool check = false; - if (m->get_op() == CEPH_CAP_OP_IMPORT && m->get_wanted() != wanted) + if ((was_stale || m->get_op() == CEPH_CAP_OP_IMPORT) && + (wanted & ~(cap->wanted | new_caps))) { + // If mds is importing cap, prior cap messages that update 'wanted' + // may get dropped by mds (migrate seq mismatch). + // + // We don't send cap message to update 'wanted' if what we want are + // already issued. If mds revokes caps, cap message that releases caps + // also tells mds what we want. But if caps got revoked by mds forcedly + // (session stale). We may haven't told mds what we want. check = true; + } check_cap_issue(in, cap, new_caps);