From 0faa143a459c00b1cf6b562873e446a69467cef1 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Mon, 14 May 2018 11:34:42 +0800 Subject: [PATCH] mds: properly setup client_need_snapflush for snap inode MDCache::cow_inode() checks "cap->issued() & CEPH_CAP_ANY_WR" to decide if it needs to setup client_need_snapflush for the new snap inode. If cap message flushes dirty caps and releases the same caps, cap->issued() may have no WR caps when MDCache::cow_inode() gets called. The solution is temporarily setting NEEDSNAPFLUSH on Capability::state. Signed-off-by: "Yan, Zheng" (cherry picked from commit 9fb61cd65895dbdb92cb46d24be8bf79ce57409d) --- src/mds/Locker.cc | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index 0cdd0e74de7e9..09b17694c3b02 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -2892,9 +2892,8 @@ void Locker::handle_client_caps(MClientCaps *m) dout(10) << " revocation in progress, not making any conclusions about null snapflushes" << dendl; } } - if (cap->need_snapflush() && !(m->flags & MClientCaps::FLAG_PENDING_CAPSNAP)) - cap->clear_needsnapflush(); + bool need_snapflush = cap->need_snapflush(); if (m->get_dirty() && in->is_auth()) { dout(7) << " flush client." << client << " dirty " << ccap_string(m->get_dirty()) << " seq " << m->get_seq() << " on " << *in << dendl; @@ -2902,6 +2901,11 @@ void Locker::handle_client_caps(MClientCaps *m) m->get_caps(), 0, m->get_dirty(), 0, mds->get_osd_epoch_barrier()); ack->set_client_tid(m->get_client_tid()); ack->set_oldest_flush_tid(m->get_oldest_flush_tid()); + + // client flushes and releases caps at the same time. make sure MDCache::cow_inode() + // properly setup CInode::client_need_snapflush + if ((m->get_dirty() & ~cap->issued()) && !need_snapflush) + cap->mark_needsnapflush(); } // filter wanted based on what we could ever give out (given auth/replica status) @@ -2915,10 +2919,15 @@ void Locker::handle_client_caps(MClientCaps *m) adjust_cap_wanted(cap, new_wanted, m->get_issue_seq()); } - - if (in->is_auth() && - _do_cap_update(in, cap, m->get_dirty(), follows, m, ack, &need_flush)) { - // updated + + bool updated = in->is_auth() && + _do_cap_update(in, cap, m->get_dirty(), follows, m, ack, &need_flush); + + if (cap->need_snapflush() && + (!need_snapflush || !(m->flags & MClientCaps::FLAG_PENDING_CAPSNAP))) + cap->clear_needsnapflush(); + + if (updated) { eval(in, CEPH_CAP_LOCKS); if (!need_flush && (cap->wanted() & ~cap->pending())) -- 2.39.5