From: Venky Shankar Date: Thu, 20 Oct 2022 10:06:39 +0000 (-0400) Subject: client: update {m,c}time and change attr for snapdir from last modification time... X-Git-Tag: v18.1.2~4^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=998dbca4e17c7f04fa7e75026ab3baa8b2831f2e;p=ceph.git client: update {m,c}time and change attr for snapdir from last modification time of a snap realm For MDS that do not encode the "new" SnapReamInfo strucutre, fallback to using SnapRealmInfo. Signed-off-by: Venky Shankar (cherry picked from commit af4739bdc256a098eaf214fd4ef9d0cf59232a2f) --- diff --git a/src/client/Client.cc b/src/client/Client.cc index 473a3c62db2a..a2a885607027 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -1512,7 +1512,7 @@ Inode* Client::insert_trace(MetaRequest *request, MetaSession *session) // snap trace SnapRealm *realm = NULL; if (reply->snapbl.length()) - update_snap_trace(reply->snapbl, &realm); + update_snap_trace(session, reply->snapbl, &realm); ldout(cct, 10) << " hrm " << " is_target=" << (int)reply->head.is_target @@ -5028,8 +5028,31 @@ static bool has_new_snaps(const SnapContext& old_snapc, return !new_snapc.snaps.empty() && new_snapc.snaps[0] > old_snapc.seq; } +struct SnapRealmInfoMeta { + SnapRealmInfoMeta(utime_t last_modified, uint64_t change_attr) + : last_modified(last_modified), + change_attr(change_attr) { + } + + utime_t last_modified; + uint64_t change_attr; +}; + +static std::pair> get_snap_realm_info( + MetaSession *session, bufferlist::const_iterator &p) { + if (session->mds_features.test(CEPHFS_FEATURE_NEW_SNAPREALM_INFO)) { + SnapRealmInfoNew ninfo; + decode(ninfo, p); + return std::make_pair(ninfo.info, SnapRealmInfoMeta(ninfo.last_modified, ninfo.change_attr)); + } else { + SnapRealmInfo info; + decode(info, p); + return std::make_pair(info, std::nullopt); + } +} + -void Client::update_snap_trace(const bufferlist& bl, SnapRealm **realm_ret, bool flush) +void Client::update_snap_trace(MetaSession *session, const bufferlist& bl, SnapRealm **realm_ret, bool flush) { SnapRealm *first_realm = NULL; ldout(cct, 10) << __func__ << " len " << bl.length() << dendl; @@ -5038,15 +5061,15 @@ void Client::update_snap_trace(const bufferlist& bl, SnapRealm **realm_ret, bool auto p = bl.cbegin(); while (!p.end()) { - SnapRealmInfo info; - decode(info, p); + auto [info, realm_info_meta] = get_snap_realm_info(session, p); SnapRealm *realm = get_snap_realm(info.ino()); bool invalidate = false; - if (info.seq() > realm->seq) { + if (info.seq() > realm->seq || + (realm_info_meta && (*realm_info_meta).change_attr > realm->change_attr)) { ldout(cct, 10) << __func__ << " " << *realm << " seq " << info.seq() << " > " << realm->seq - << dendl; + << dendl; if (flush) { // writeback any dirty caps _before_ updating snap list (i.e. with old snap info) @@ -5074,6 +5097,10 @@ void Client::update_snap_trace(const bufferlist& bl, SnapRealm **realm_ret, bool realm->created = info.created(); realm->parent_since = info.parent_since(); realm->prior_parent_snaps = info.prior_parent_snaps; + if (realm_info_meta) { + realm->last_modified = (*realm_info_meta).last_modified; + realm->change_attr = (*realm_info_meta).change_attr; + } realm->my_snaps = info.my_snaps; invalidate = true; } @@ -5134,9 +5161,8 @@ void Client::handle_snap(const MConstRef& m) if (m->head.op == CEPH_SNAP_OP_SPLIT) { ceph_assert(m->head.split); - SnapRealmInfo info; auto p = m->bl.cbegin(); - decode(info, p); + auto [info, _] = get_snap_realm_info(session.get(), p); ceph_assert(info.ino() == m->head.split); // flush, then move, ino's. @@ -5173,7 +5199,7 @@ void Client::handle_snap(const MConstRef& m) } } - update_snap_trace(m->bl, NULL, m->head.op != CEPH_SNAP_OP_DESTROY); + update_snap_trace(session.get(), m->bl, NULL, m->head.op != CEPH_SNAP_OP_DESTROY); if (realm) { for (auto p = to_move.begin(); p != to_move.end(); ++p) { @@ -5298,7 +5324,7 @@ void Client::handle_cap_import(MetaSession *session, Inode *in, const MConstRef< // add/update it SnapRealm *realm = NULL; - update_snap_trace(m->snapbl, &realm); + update_snap_trace(session, m->snapbl, &realm); int issued = m->get_caps(); int wanted = m->get_wanted(); @@ -11947,12 +11973,12 @@ void Client::refresh_snapdir_attrs(Inode *in, Inode *diri) { in->uid = diri->uid; in->gid = diri->gid; in->nlink = 1; - in->mtime = diri->mtime; - in->ctime = diri->ctime; + in->mtime = diri->snaprealm->last_modified; + in->ctime = in->mtime; + in->change_attr = diri->snaprealm->change_attr; in->btime = diri->btime; in->atime = diri->atime; in->size = diri->size; - in->change_attr = diri->change_attr; in->dirfragtree.clear(); in->snapdir_parent = diri; diff --git a/src/client/Client.h b/src/client/Client.h index 73a603397afd..e0c29db8a6b5 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -982,7 +982,7 @@ protected: SnapRealm *get_snap_realm_maybe(inodeno_t r); void put_snap_realm(SnapRealm *realm); bool adjust_realm_parent(SnapRealm *realm, inodeno_t parent); - void update_snap_trace(const bufferlist& bl, SnapRealm **realm_ret, bool must_flush=true); + void update_snap_trace(MetaSession *session, const bufferlist& bl, SnapRealm **realm_ret, bool must_flush=true); void invalidate_snaprealm_and_children(SnapRealm *realm); void refresh_snapdir_attrs(Inode *in, Inode *diri); diff --git a/src/client/ClientSnapRealm.h b/src/client/ClientSnapRealm.h index 730c87eec5fa..17f45dbc9011 100644 --- a/src/client/ClientSnapRealm.h +++ b/src/client/ClientSnapRealm.h @@ -23,6 +23,8 @@ struct SnapRealm { SnapRealm *pparent; std::set pchildren; + utime_t last_modified; + uint64_t change_attr; private: SnapContext cached_snap_context; // my_snaps + parent snaps + past_parent_snaps @@ -33,7 +35,7 @@ public: explicit SnapRealm(inodeno_t i) : ino(i), nref(0), created(0), seq(0), - pparent(NULL) { } + pparent(NULL), last_modified(utime_t()), change_attr(0) { } void build_snap_context(); void invalidate_cache() { @@ -54,6 +56,8 @@ inline std::ostream& operator<<(std::ostream& out, const SnapRealm& r) { << " parent=" << r.parent << " my_snaps=" << r.my_snaps << " cached_snapc=" << r.cached_snap_context + << " last_modified=" << r.last_modified + << " change_attr=" << r.change_attr << ")"; }