From e4dc3e5fe48ec22907bb198872654b4d7d9df0fc Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Sat, 26 Jul 2008 08:14:02 -0700 Subject: [PATCH] mds: condition dir fetch/commit snap purge on last_destroyed, not seq --- src/mds/CDir.cc | 16 ++++++++-------- src/mds/Server.cc | 9 +++++++-- src/mds/snap.cc | 47 ++++++++++++++++++++++++----------------------- src/mds/snap.h | 19 ++++++++++++++----- 4 files changed, 53 insertions(+), 38 deletions(-) diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc index ec4a15d4c52e4..3f66ba03d4be5 100644 --- a/src/mds/CDir.cc +++ b/src/mds/CDir.cc @@ -1047,8 +1047,8 @@ void CDir::_fetched(bufferlist &bl) int32_t n; ::decode(n, p); - snapid_t got_newest_seq; - ::decode(got_newest_seq, p); + snapid_t got_last_destroyed; + ::decode(got_last_destroyed, p); // purge stale snaps? // * only if we have past_parents open! @@ -1056,9 +1056,9 @@ void CDir::_fetched(bufferlist &bl) SnapRealm *realm = inode->find_snaprealm(); if (!realm->have_past_parents_open()) { dout(10) << " no snap purge, one or more past parents NOT open" << dendl; - } else if (got_newest_seq < realm->get_newest_seq()) { + } else if (got_last_destroyed < realm->get_last_destroyed()) { snaps = &realm->get_snaps(); - dout(10) << " got newest_seq " << got_newest_seq << " < " << realm->get_newest_seq() + dout(10) << " got last_destroyed " << got_last_destroyed << " < " << realm->get_last_destroyed() << ", snap purge based on " << *snaps << dendl; } @@ -1361,18 +1361,18 @@ void CDir::_commit(version_t want) int32_t n = num_head_items + num_snap_items; ::encode(n, bl); + SnapRealm *realm = inode->find_snaprealm(); + snapid_t last_destroyed = realm->get_last_destroyed(); + ::encode(last_destroyed, bl); + // snap purge? const set *snaps = 0; - snapid_t newest_seq = 0; - SnapRealm *realm = inode->find_snaprealm(); if (realm->have_past_parents_open()) { snaps = &realm->get_snaps(); - newest_seq = realm->get_newest_seq(); dout(10) << " snap purge based on " << *snaps << dendl; } else { dout(10) << " no snap purge, one or more past parents NOT open" << dendl; } - ::encode(newest_seq, bl); map_t::iterator p = items.begin(); while (p != items.end()) { diff --git a/src/mds/Server.cc b/src/mds/Server.cc index c173152e38d09..639095f50e44d 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -5178,12 +5178,15 @@ void Server::handle_client_rmsnap(MDRequest *mdr) // project the snaprealm.. hack! bufferlist snapbl; snapid_t old_seq = diri->snaprealm->seq; + snapid_t old_ld = diri->snaprealm->last_destroyed; SnapInfo old_info = diri->snaprealm->snaps[snapid]; diri->snaprealm->snaps.erase(snapid); diri->snaprealm->seq = stid; + diri->snaprealm->last_destroyed = stid; diri->encode_snap_blob(snapbl); diri->snaprealm->snaps[snapid] = old_info; diri->snaprealm->seq = old_seq; + diri->snaprealm->last_destroyed = old_ld; le->metablob.add_primary_dentry(diri->get_projected_parent_dn(), true, 0, pi, 0, &snapbl); mdlog->submit_entry(le, new C_MDS_rmsnap_finish(mds, mdr, diri, snapid)); @@ -5192,15 +5195,17 @@ void Server::handle_client_rmsnap(MDRequest *mdr) void Server::_rmsnap_finish(MDRequest *mdr, CInode *diri, snapid_t snapid) { dout(10) << "_rmsnap_finish " << *mdr << " " << snapid << dendl; + snapid_t stid = mdr->more()->stid; diri->pop_and_dirty_projected_inode(mdr->ls); mdr->apply(); - mds->snapclient->commit(mdr->more()->stid, mdr->ls); + mds->snapclient->commit(stid, mdr->ls); // remove snap diri->snaprealm->snaps.erase(snapid); - diri->snaprealm->seq = mdr->more()->stid; + diri->snaprealm->last_destroyed = stid; + diri->snaprealm->seq = stid; dout(10) << "snaprealm now " << *diri->snaprealm << dendl; _invalidate_and_send_snap_updates(diri, CEPH_SNAP_OP_DESTROY); diff --git a/src/mds/snap.cc b/src/mds/snap.cc index 79ec9c8ccc3e9..cdf32ddf86e76 100644 --- a/src/mds/snap.cc +++ b/src/mds/snap.cc @@ -106,7 +106,7 @@ void SnapRealm::close_parents() * for the intervals during which they were our parent. */ void SnapRealm::build_snap_set(set &s, - snapid_t& max_seq, snapid_t& max_last_created, + snapid_t& max_seq, snapid_t& max_last_created, snapid_t& max_last_destroyed, snapid_t first, snapid_t last) { dout(10) << "build_snap_set [" << first << "," << last << "] on " << *this << dendl; @@ -115,6 +115,8 @@ void SnapRealm::build_snap_set(set &s, max_seq = seq; if (last_created > max_last_created) max_last_created = last_created; + if (last_destroyed > max_last_destroyed) + max_last_destroyed = last_destroyed; // include my snaps within interval [first,last] for (map::iterator p = snaps.lower_bound(first); // first element >= first @@ -129,19 +131,16 @@ void SnapRealm::build_snap_set(set &s, CInode *oldparent = mdcache->get_inode(p->second.ino); assert(oldparent); // call open_parents first! assert(oldparent->snaprealm); - - snapid_t thru = MIN(last, p->first); - oldparent->snaprealm->build_snap_set(s, max_seq, max_last_created, + oldparent->snaprealm->build_snap_set(s, max_seq, max_last_created, max_last_destroyed, MAX(first, p->second.first), - thru); + MIN(last, p->first)); } if (current_parent_since <= last && parent) - parent->build_snap_set(s, max_seq, max_last_created, current_parent_since, last); + parent->build_snap_set(s, max_seq, max_last_created, max_last_destroyed, + MAX(first, current_parent_since), last); } -/* - * build vector in reverse sorted order - */ + void SnapRealm::check_cache() { if (cached_seq >= seq) @@ -150,14 +149,17 @@ void SnapRealm::check_cache() cached_snaps.clear(); cached_snap_vec.clear(); cached_last_created = last_created; + cached_last_destroyed = last_destroyed; cached_seq = seq; - build_snap_set(cached_snaps, cached_seq, cached_last_created, 0, CEPH_NOSNAP); + build_snap_set(cached_snaps, cached_seq, cached_last_created, cached_last_destroyed, + 0, CEPH_NOSNAP); dout(10) << "check_cache " << cached_snaps << " seq " << seq << " cached_seq " << cached_seq - << " cached_last_created " << cached_last_created << ")" - << dendl; + << " cached_last_created " << cached_last_created + << " cached_last_destroyed " << cached_last_destroyed + << ")" << dendl; } const set& SnapRealm::get_snaps() @@ -169,6 +171,9 @@ const set& SnapRealm::get_snaps() return cached_snaps; } +/* + * build vector in reverse sorted order + */ const vector& SnapRealm::get_snap_vector() { check_cache(); @@ -202,14 +207,12 @@ void SnapRealm::get_snap_info(map& infomap, snapid_t first, CInode *oldparent = mdcache->get_inode(p->second.ino); assert(oldparent); // call open_parents first! assert(oldparent->snaprealm); - - snapid_t thru = MIN(last, p->first); oldparent->snaprealm->get_snap_info(infomap, MAX(first, p->second.first), - thru); + MIN(last, p->first)); } if (current_parent_since <= last && parent) - parent->get_snap_info(infomap, current_parent_since, last); + parent->get_snap_info(infomap, MAX(first, current_parent_since), last); } const string& SnapInfo::get_long_name() @@ -284,16 +287,14 @@ snapid_t SnapRealm::resolve_snapname(const string& n, inodeno_t atino, snapid_t CInode *oldparent = mdcache->get_inode(p->second.ino); assert(oldparent); // call open_parents first! assert(oldparent->snaprealm); - - snapid_t thru = MIN(last, p->first); snapid_t r = oldparent->snaprealm->resolve_snapname(n, atino, MAX(first, p->second.first), - thru); + MIN(last, p->first)); if (r) return r; } - if (current_parent_since <= last && parent) - return parent->resolve_snapname(n, atino, current_parent_since, last); + if (parent && current_parent_since <= last) + return parent->resolve_snapname(n, atino, MAX(first, current_parent_since), last); return 0; } @@ -364,8 +365,8 @@ void SnapRealm::build_snap_trace(bufferlist& snapbl) if (!past_parents.empty()) { snapid_t last = past_parents.rbegin()->first; set past; - snapid_t max_seq, max_last_created; - build_snap_set(past, max_seq, max_last_created, 0, last); + snapid_t max_seq, max_last_created, max_last_destroyed; + build_snap_set(past, max_seq, max_last_created, max_last_destroyed, 0, last); info.prior_parent_snaps.reserve(past.size()); for (set::reverse_iterator p = past.rbegin(); p != past.rend(); p++) info.prior_parent_snaps.push_back(*p); diff --git a/src/mds/snap.h b/src/mds/snap.h index c29fa93449052..d689a390d3434 100644 --- a/src/mds/snap.h +++ b/src/mds/snap.h @@ -81,25 +81,28 @@ WRITE_CLASS_ENCODER(snaplink_t) struct SnapRealm { // realm state + snapid_t seq; // basically, a version/seq # for changes to _this_ realm. snapid_t created; // when this realm was created. snapid_t last_created; // last snap created in _this_ realm. - snapid_t seq; // basically, a version/seq # for changes to _this_ realm. + snapid_t last_destroyed; // seq for last removal snapid_t current_parent_since; map snaps; map past_parents; // key is "last" (or NOSNAP) void encode(bufferlist& bl) const { + ::encode(seq, bl); ::encode(created, bl); ::encode(last_created, bl); - ::encode(seq, bl); + ::encode(last_destroyed, bl); ::encode(current_parent_since, bl); ::encode(snaps, bl); ::encode(past_parents, bl); } void decode(bufferlist::iterator& p) { + ::decode(seq, p); ::decode(created, p); ::decode(last_created, p); - ::decode(seq, p); + ::decode(last_destroyed, p); ::decode(current_parent_since, p); ::decode(snaps, p); ::decode(past_parents, p); @@ -117,6 +120,7 @@ struct SnapRealm { // cache snapid_t cached_seq; // max seq over self and all past+present parents. snapid_t cached_last_created; // max last_created over all past+present parents + snapid_t cached_last_destroyed; set cached_snaps; vector cached_snap_vec; @@ -124,7 +128,8 @@ struct SnapRealm { map > client_caps; // to identify clients who need snap notifications SnapRealm(MDCache *c, CInode *in) : - created(0), last_created(0), seq(0), + seq(0), created(0), + last_created(0), last_destroyed(0), current_parent_since(1), mdcache(c), inode(in), open(false), parent(0) @@ -144,7 +149,7 @@ struct SnapRealm { void close_parents(); void build_snap_set(set& s, - snapid_t& max_seq, snapid_t& max_last_created, + snapid_t& max_seq, snapid_t& max_last_created, snapid_t& max_last_destroyed, snapid_t first, snapid_t last); void get_snap_info(map& infomap, snapid_t first=0, snapid_t last=CEPH_NOSNAP); @@ -163,6 +168,10 @@ struct SnapRealm { check_cache(); return cached_last_created; } + snapid_t get_last_destroyed() { + check_cache(); + return cached_last_created; + } snapid_t get_newest_snap() { check_cache(); if (cached_snaps.empty()) -- 2.39.5