From: Yan, Zheng Date: Thu, 20 Jun 2019 09:39:28 +0000 (+0800) Subject: client: more precise CEPH_CLIENT_CAPS_PENDING_CAPSNAP X-Git-Tag: v14.2.5~216^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=afa4057492555da14800d3dffc9b854bd5c1bae8;p=ceph.git client: more precise CEPH_CLIENT_CAPS_PENDING_CAPSNAP Client uses this flag to tell mds if there is more cap snap need to flush. It's mainly for the case that client needs to re-send cap/snap flushes after mds failover, but CEPH_CAP_ANY_FILE_WR on corresponding inodes are all released before mds failover Fixes: https://tracker.ceph.com/issues/40474 Signed-off-by: "Yan, Zheng" (cherry picked from commit 8628340e28208ad63019a6da61642f48fbde6313) --- diff --git a/src/client/Client.cc b/src/client/Client.cc index 946006730c5..89a00bc9c62 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -3309,7 +3309,7 @@ void Client::cap_delay_requeue(Inode *in) } void Client::send_cap(Inode *in, MetaSession *session, Cap *cap, - bool sync, int used, int want, int retain, + int flags, int used, int want, int retain, int flush, ceph_tid_t flush_tid) { int held = cap->issued | cap->implemented; @@ -3320,7 +3320,6 @@ void Client::send_cap(Inode *in, MetaSession *session, Cap *cap, ldout(cct, 10) << __func__ << " " << *in << " mds." << session->mds_num << " seq " << cap->seq - << (sync ? " sync " : " async ") << " used " << ccap_string(used) << " want " << ccap_string(want) << " flush " << ccap_string(flush) @@ -3395,11 +3394,13 @@ void Client::send_cap(Inode *in, MetaSession *session, Cap *cap, m->btime = in->btime; m->time_warp_seq = in->time_warp_seq; m->change_attr = in->change_attr; - if (sync) - m->flags |= MClientCaps::FLAG_SYNC; - if (!in->cap_snaps.empty()) - m->flags |= MClientCaps::FLAG_PENDING_CAPSNAP; - + + if (!(flags & MClientCaps::FLAG_PENDING_CAPSNAP) && + !in->cap_snaps.empty() && + in->cap_snaps.rbegin()->second.flush_tid == 0) + flags |= MClientCaps::FLAG_PENDING_CAPSNAP; + m->flags = flags; + if (flush & CEPH_CAP_FILE_WR) { m->inline_version = in->inline_version; m->inline_data = in->inline_data; @@ -3603,8 +3604,9 @@ void Client::check_caps(Inode *in, unsigned flags) flush_tid = 0; } - send_cap(in, session, &cap, flags & CHECK_CAPS_SYNCHRONOUS, cap_used, wanted, - retain, flushing, flush_tid); + int msg_flags = (flags & CHECK_CAPS_SYNCHRONOUS) ? MClientCaps::FLAG_SYNC : 0; + send_cap(in, session, &cap, msg_flags, cap_used, wanted, retain, + flushing, flush_tid); } } @@ -4427,13 +4429,23 @@ void Client::kick_flushing_caps(Inode *in, MetaSession *session) Cap *cap = in->auth_cap; ceph_assert(cap->session == session); + ceph_tid_t last_snap_flush = 0; + for (auto p = in->flushing_cap_tids.rbegin(); + p != in->flushing_cap_tids.rend(); + ++p) { + if (!p->second) { + last_snap_flush = p->first; + break; + } + } + int wanted = in->caps_wanted(); int used = get_caps_used(in) | in->caps_dirty(); auto it = in->cap_snaps.begin(); for (auto& p : in->flushing_cap_tids) { if (p.second) { - send_cap(in, session, cap, false, - used, wanted, (cap->issued | cap->implemented), + int msg_flags = p.first < last_snap_flush ? MClientCaps::FLAG_PENDING_CAPSNAP : 0; + send_cap(in, session, cap, msg_flags, used, wanted, (cap->issued | cap->implemented), p.second, p.first); } else { ceph_assert(it != in->cap_snaps.end()); diff --git a/src/client/Client.h b/src/client/Client.h index 608288abcd6..742cb6812fc 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -671,7 +671,7 @@ public: void handle_cap_grant(MetaSession *session, Inode *in, Cap *cap, const MConstRef& m); void cap_delay_requeue(Inode *in); - void send_cap(Inode *in, MetaSession *session, Cap *cap, bool sync, + void send_cap(Inode *in, MetaSession *session, Cap *cap, int flags, int used, int want, int retain, int flush, ceph_tid_t flush_tid);