From: Yan, Zheng Date: Mon, 18 May 2015 09:25:58 +0000 (+0800) Subject: mds: properly invalidate past child snaprealms X-Git-Tag: v9.0.2~40^2~5 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=de8b9583d377c7fd8c7760f2ef8ea74f5fc045a8;p=ceph.git mds: properly invalidate past child snaprealms After updating an existing snapshot or deleting an old snapshot, we should invalidate past child snaprealms' cached snap set and snap context. Signed-off-by: Yan, Zheng --- diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index fbcbbb7c53a..809144a2e8d 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -9013,6 +9013,7 @@ void MDCache::do_realm_invalidate_and_update_notify(CInode *in, int snapop, bool bufferlist snapbl; in->snaprealm->build_snap_trace(snapbl); + set past_children; map updates; list q; q.push_back(in->snaprealm); @@ -9037,6 +9038,13 @@ void MDCache::do_realm_invalidate_and_update_notify(CInode *in, int snapop, bool } } + if (snapop == CEPH_SNAP_OP_UPDATE || snapop == CEPH_SNAP_OP_DESTROY) { + for (set::iterator p = realm->open_past_children.begin(); + p != realm->open_past_children.end(); + ++p) + past_children.insert(*p); + } + // notify for active children, too. dout(10) << " " << realm << " open_children are " << realm->open_children << dendl; for (set::iterator p = realm->open_children.begin(); @@ -9047,6 +9055,43 @@ void MDCache::do_realm_invalidate_and_update_notify(CInode *in, int snapop, bool if (!nosend) send_snaps(updates); + + // notify past children and their descendants if we update/delete old snapshots + for (set::iterator p = past_children.begin(); + p != past_children.end(); + ++p) + q.push_back(*p); + + while (!q.empty()) { + SnapRealm *realm = q.front(); + q.pop_front(); + + realm->invalidate_cached_snaps(); + + for (set::iterator p = realm->open_children.begin(); + p != realm->open_children.end(); + ++p) { + if (past_children.count(*p) == 0) + q.push_back(*p); + } + + for (set::iterator p = realm->open_past_children.begin(); + p != realm->open_past_children.end(); + ++p) { + if (past_children.count(*p) == 0) { + q.push_back(*p); + past_children.insert(*p); + } + } + } + + if (snapop == CEPH_SNAP_OP_DESTROY) { + // eval stray inodes if we delete snapshot from their past ancestor snaprealm + for (set::iterator p = past_children.begin(); + p != past_children.end(); + ++p) + maybe_eval_stray((*p)->inode, true); + } } void MDCache::_snaprealm_create_finish(MDRequestRef& mdr, MutationRef& mut, CInode *in) diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 39a4465aa33..12de267e9e2 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -8061,7 +8061,7 @@ void Server::_renamesnap_finish(MDRequestRef& mdr, CInode *diri, snapid_t snapid dout(10) << "snaprealm now " << *diri->snaprealm << dendl; - mdcache->do_realm_invalidate_and_update_notify(diri, CEPH_SNAP_OP_CREATE, true); + mdcache->do_realm_invalidate_and_update_notify(diri, CEPH_SNAP_OP_UPDATE, true); // yay mdr->in[0] = diri; diff --git a/src/mds/SnapRealm.cc b/src/mds/SnapRealm.cc index 14af91f8f70..60d417514e4 100644 --- a/src/mds/SnapRealm.cc +++ b/src/mds/SnapRealm.cc @@ -61,6 +61,7 @@ ostream& operator<<(ostream& out, const SnapRealm& realm) void SnapRealm::add_open_past_parent(SnapRealm *parent) { open_past_parents[parent->inode->ino()] = parent; + parent->open_past_children.insert(this); parent->inode->get(CInode::PIN_PASTSNAPPARENT); } @@ -174,8 +175,10 @@ void SnapRealm::close_parents() { for (map::iterator p = open_past_parents.begin(); p != open_past_parents.end(); - ++p) + ++p) { p->second->inode->put(CInode::PIN_PASTSNAPPARENT); + p->second->open_past_children.erase(this); + } open_past_parents.clear(); } diff --git a/src/mds/SnapRealm.h b/src/mds/SnapRealm.h index cd0de824d25..ad55adc0172 100644 --- a/src/mds/SnapRealm.h +++ b/src/mds/SnapRealm.h @@ -35,6 +35,7 @@ struct SnapRealm { SnapRealm *parent; set open_children; // active children that are currently open map open_past_parents; // these are explicitly pinned. + set open_past_children; // past children who has pinned me // cache snapid_t cached_seq; // max seq over self and all past+present parents.