From 7e264678a9324fc247f29fcad1b1cf4ac818dd3b Mon Sep 17 00:00:00 2001 From: Samuel Just Date: Fri, 2 Nov 2012 13:02:15 -0700 Subject: [PATCH] PG: use remove_object_with_snap_hardlinks for divergent objects Otherwise, we end up leaving snap hardlinks in the snapshot index directories. This eventually results in an EEXIST error when we attempt to re-link the clone into place during recovery. Signed-off-by: Samuel Just Reviewed-by: Sage Weil --- src/osd/PG.cc | 23 ++++++++++++++++++++--- src/osd/PG.h | 2 ++ src/osd/ReplicatedPG.cc | 16 ---------------- src/osd/ReplicatedPG.h | 1 - 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/osd/PG.cc b/src/osd/PG.cc index ec9a495074b37..7799ceec1cb05 100644 --- a/src/osd/PG.cc +++ b/src/osd/PG.cc @@ -319,6 +319,23 @@ bool PG::proc_replica_info(int from, const pg_info_t &oinfo) return true; } +void PG::remove_object_with_snap_hardlinks( + ObjectStore::Transaction& t, const hobject_t& soid) +{ + t.remove(coll, soid); + if (soid.snap < CEPH_MAXSNAP) { + bufferlist ba; + int r = osd->store->getattr(coll, soid, OI_ATTR, ba); + if (r >= 0) { + // grr, need first snap bound, too. + object_info_t oi(ba); + if (oi.snaps.size() > 1) + t.remove(coll_t(info.pgid, oi.snaps[oi.snaps.size() - 1]), soid); + t.remove(coll_t(info.pgid, oi.snaps[0]), soid); + } + } +} + /* * merge an old (possibly divergent) log entry into the new log. this @@ -371,13 +388,13 @@ bool PG::merge_old_entry(ObjectStore::Transaction& t, pg_log_entry_t& oe) dout(20) << "merge_old_entry had " << oe << ", clone with no non-divergent log entries, " << "deleting" << dendl; - t.remove(coll, oe.soid); + remove_object_with_snap_hardlinks(t, oe.soid); if (missing.is_missing(oe.soid)) missing.rm(oe.soid, missing.missing[oe.soid].need); } else { if (!oe.is_delete()) { dout(20) << "merge_old_entry had " << oe << " deleting" << dendl; - t.remove(coll, oe.soid); + remove_object_with_snap_hardlinks(t, oe.soid); } dout(20) << "merge_old_entry had " << oe << " reverting to " << oe.prior_version << dendl; @@ -530,7 +547,7 @@ void PG::merge_log(ObjectStore::Transaction& t, if (ne.soid <= info.last_backfill) { missing.add_next_event(ne); if (ne.is_delete()) - t.remove(coll, ne.soid); + remove_object_with_snap_hardlinks(t, ne.soid); } } diff --git a/src/osd/PG.h b/src/osd/PG.h index 15a0061073147..5d9f2280c796e 100644 --- a/src/osd/PG.h +++ b/src/osd/PG.h @@ -715,6 +715,8 @@ public: void proc_master_log(ObjectStore::Transaction& t, pg_info_t &oinfo, pg_log_t &olog, pg_missing_t& omissing, int from); bool proc_replica_info(int from, const pg_info_t &info); + void remove_object_with_snap_hardlinks( + ObjectStore::Transaction& t, const hobject_t& soid); bool merge_old_entry(ObjectStore::Transaction& t, pg_log_entry_t& oe); /** diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index 336cb91697144..b85580d41d917 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -6709,22 +6709,6 @@ void ReplicatedPG::scan_range(hobject_t begin, int min, int max, BackfillInterva } -void ReplicatedPG::remove_object_with_snap_hardlinks(ObjectStore::Transaction& t, const hobject_t& soid) -{ - t.remove(coll, soid); - if (soid.snap < CEPH_MAXSNAP) { - bufferlist ba; - int r = osd->store->getattr(coll, soid, OI_ATTR, ba); - if (r >= 0) { - // grr, need first snap bound, too. - object_info_t oi(ba); - if (oi.snaps.size() > 1) - t.remove(coll_t(info.pgid, oi.snaps[oi.snaps.size() - 1]), soid); - t.remove(coll_t(info.pgid, oi.snaps[0]), soid); - } - } -} - /** clean_up_local * remove any objects that we're storing but shouldn't. * as determined by log. diff --git a/src/osd/ReplicatedPG.h b/src/osd/ReplicatedPG.h index 7302e0bd6f5bb..a786e2b966a5e 100644 --- a/src/osd/ReplicatedPG.h +++ b/src/osd/ReplicatedPG.h @@ -783,7 +783,6 @@ protected: int prepare_transaction(OpContext *ctx); // pg on-disk content - void remove_object_with_snap_hardlinks(ObjectStore::Transaction& t, const hobject_t& soid); void clean_up_local(ObjectStore::Transaction& t); void _clear_recovery_state(); -- 2.39.5