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: v15.1.0~2060^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=8628340e28208ad63019a6da61642f48fbde6313;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" --- diff --git a/src/client/Client.cc b/src/client/Client.cc index 04aa0dad1003..cf84fa40af4e 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -3311,7 +3311,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; @@ -3322,7 +3322,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) @@ -3397,11 +3396,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; @@ -3605,8 +3606,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); } } @@ -4429,13 +4431,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 e6bb541be09d..4e43da16343f 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);