From 06bdd79620b1d40d871d4f6ae2ea794c34bf722c Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Mon, 14 May 2018 10:48:16 +0800 Subject: [PATCH] Revert "mds: properly setup need_snapflush for snapped inode" commit de3f3d88b3e make Locker::_do_cap_update() get called before adjusting wanted caps. This is wrong because Locker::_do_cap_update() need uptodate wanted caps to calculate max size. Signed-off-by: "Yan, Zheng" Fixes: https://tracker.ceph.com/issues/24111 (cherry picked from commit 4b13d3ffe260fa4539e2d341604c34d2e8df7c94) --- src/mds/Locker.cc | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index e8955697ff1b0..0cdd0e74de7e9 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -2868,32 +2868,19 @@ void Locker::handle_client_caps(MClientCaps *m) caps &= cap->issued(); } + cap->confirm_receipt(m->get_seq(), caps); dout(10) << " follows " << follows << " retains " << ccap_string(m->get_caps()) << " dirty " << ccap_string(m->get_dirty()) << " on " << *in << dendl; - 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; - ack = new MClientCaps(CEPH_CAP_OP_FLUSH_ACK, in->ino(), 0, cap->get_cap_id(), m->get_seq(), - 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()); - } - - bool need_flush = m->flags & MClientCaps::FLAG_SYNC; - bool updated = in->is_auth() && - _do_cap_update(in, cap, m->get_dirty(), follows, m, ack, &need_flush); - - cap->confirm_receipt(m->get_seq(), caps); // missing/skipped snapflush? - // The client MAY send a snapflush if it is issued WR/EXCL caps, - // but only does so when it has actual dirty metadata. We set up - // the need_snapflush stuff based on the issued caps. We can infer - // that the client WONT send a FLUSHSNAP once they have released - // all WR/EXCL caps (the FLUSHSNAP always comes before the cap + // The client MAY send a snapflush if it is issued WR/EXCL caps, but + // presently only does so when it has actual dirty metadata. But, we + // set up the need_snapflush stuff based on the issued caps. + // We can infer that the client WONT send a FLUSHSNAP once they have + // released all WR/EXCL caps (the FLUSHSNAP always comes before the cap // update/release). if (!head_in->client_need_snapflush.empty()) { if (!(cap->issued() & CEPH_CAP_ANY_FILE_WR) && @@ -2908,7 +2895,17 @@ void Locker::handle_client_caps(MClientCaps *m) if (cap->need_snapflush() && !(m->flags & MClientCaps::FLAG_PENDING_CAPSNAP)) cap->clear_needsnapflush(); + 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; + ack = new MClientCaps(CEPH_CAP_OP_FLUSH_ACK, in->ino(), 0, cap->get_cap_id(), m->get_seq(), + 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()); + } + // filter wanted based on what we could ever give out (given auth/replica status) + bool need_flush = m->flags & MClientCaps::FLAG_SYNC; int new_wanted = m->get_wanted() & head_in->get_caps_allowed_ever(); if (new_wanted != cap->wanted()) { if (!need_flush && (new_wanted & ~cap->pending())) { @@ -2919,7 +2916,8 @@ void Locker::handle_client_caps(MClientCaps *m) adjust_cap_wanted(cap, new_wanted, m->get_issue_seq()); } - if (updated) { + if (in->is_auth() && + _do_cap_update(in, cap, m->get_dirty(), follows, m, ack, &need_flush)) { // updated eval(in, CEPH_CAP_LOCKS); -- 2.39.5