From: Sage Weil Date: Sat, 11 Feb 2012 22:55:06 +0000 (-0800) Subject: osd: filter trimming|purged snaps out of op SnapContext X-Git-Tag: v0.42~31 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=7c6dff487171deb37852e2fb059dcb6e3af65702;p=ceph.git osd: filter trimming|purged snaps out of op SnapContext We can receive an op with an old SnapContext that includes snaps that we've already trimmed or are in the process of trimming. Filter them out! Otherwise we will recreate and add links into collections we've already marked as removed, and we'll get things like ENOTEMPTY when we try to remove them. Or just leave them laying around. Fixes: #1949 Signed-off-by: Sage Weil --- diff --git a/src/osd/PG.cc b/src/osd/PG.cc index edaae82123aa..146d57ebb7a3 100644 --- a/src/osd/PG.cc +++ b/src/osd/PG.cc @@ -2262,6 +2262,36 @@ void PG::update_snap_collections(vector &log_entries, } } +/** + * filter trimming|trimmed snaps out of snapcontext + */ +void PG::filter_snapc(SnapContext& snapc) +{ + bool filtering = false; + vector newsnaps; + for (vector::iterator p = snapc.snaps.begin(); + p != snapc.snaps.end(); + ++p) { + if (snap_trimq.contains(*p) || info.purged_snaps.contains(*p)) { + if (!filtering) { + // start building a new vector with what we've seen so far + dout(10) << "filter_snapc filtering " << snapc << dendl; + newsnaps.insert(newsnaps.begin(), snapc.snaps.begin(), p); + filtering = true; + } + dout(20) << "filter_snapc removing trimq|purged snap " << *p << dendl; + } else { + if (filtering) + newsnaps.push_back(*p); // continue building new vector + } + } + if (filtering) { + snapc.snaps.swap(newsnaps); + dout(10) << "filter_snapc result " << snapc << dendl; + } +} + + void PG::adjust_local_snaps() { interval_set to_remove; diff --git a/src/osd/PG.h b/src/osd/PG.h index 02466b9a8e92..791cd6721ed1 100644 --- a/src/osd/PG.h +++ b/src/osd/PG.h @@ -1310,6 +1310,7 @@ public: coll_t make_snap_collection(ObjectStore::Transaction& t, snapid_t sn); void update_snap_collections(vector &log_entries, ObjectStore::Transaction& t); + void filter_snapc(SnapContext& snapc); void adjust_local_snaps(); void log_weirdness(); diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index b98a4e6308ef..e42c317af072 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -2427,6 +2427,9 @@ void ReplicatedPG::make_writeable(OpContext *ctx) snapc.snaps = ctx->new_snapset.snaps; dout(10) << " using newer snapc " << snapc << dendl; } + + if (ctx->obs->exists) + filter_snapc(snapc); if (ctx->obs->exists && // head exist(ed) snapc.snaps.size() && // there are snaps