From 16c5bcc0218069edcd5e16b8d17912d47b8e70b3 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 13 Oct 2017 10:39:51 -0500 Subject: [PATCH] osd/osd_types: pg_pool_t: add FLAG_{SELFMANAGED,POOL}_SNAPS flags Explicitly track whether we are a pool snaps pool or a selfmanaged snaps pool. This was inferred from removed_snaps.empty() before, but that was fragile and kludgey and removed_snaps is going away. The upgrade/compat behavior is a bit tricky: - on decode, we set the flags based on the legacy condition. This lets us use and rely on the flags in memory. - on encode, we exclude the flags if decoding an older pg_pool_t Signed-off-by: Sage Weil --- src/osd/osd_types.cc | 40 ++++++++++++++++++++++++++++++---------- src/osd/osd_types.h | 8 ++++++++ 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/osd/osd_types.cc b/src/osd/osd_types.cc index 6cd18c2ef6fa9..2e56f8dbeebcd 100644 --- a/src/osd/osd_types.cc +++ b/src/osd/osd_types.cc @@ -1266,21 +1266,19 @@ unsigned pg_pool_t::get_pg_num_divisor(pg_t pgid) const /* * we have two snap modes: - * - pool global snaps + * - pool snaps * - snap existence/non-existence defined by snaps[] and snap_seq * - user managed snaps - * - removal governed by removed_snaps - * - * we know which mode we're using based on whether removed_snaps is empty. + * - existence tracked by librados user */ bool pg_pool_t::is_pool_snaps_mode() const { - return removed_snaps.empty() && get_snap_seq() > 0; + return has_flag(FLAG_POOL_SNAPS); } bool pg_pool_t::is_unmanaged_snaps_mode() const { - return removed_snaps.size() && get_snap_seq() > 0; + return has_flag(FLAG_SELFMANAGED_SNAPS); } bool pg_pool_t::is_removed_snap(snapid_t s) const @@ -1330,6 +1328,7 @@ snapid_t pg_pool_t::snap_exists(const char *s) const void pg_pool_t::add_snap(const char *n, utime_t stamp) { assert(!is_unmanaged_snaps_mode()); + flags |= FLAG_POOL_SNAPS; snapid_t s = get_snap_seq() + 1; snap_seq = s; snaps[s].snapid = s; @@ -1339,11 +1338,15 @@ void pg_pool_t::add_snap(const char *n, utime_t stamp) void pg_pool_t::add_unmanaged_snap(uint64_t& snapid) { - if (removed_snaps.empty()) { - assert(!is_pool_snaps_mode()); + assert(!is_pool_snaps_mode()); + if (snap_seq == 0) { + // kludge for pre-mimic tracking of pool vs selfmanaged snaps. after + // mimic this field is not decoded but our flag is set; pre-mimic, we + // have a non-empty removed_snaps to signifiy a non-pool-snaps pool. removed_snaps.insert(snapid_t(1)); snap_seq = 1; } + flags |= FLAG_SELFMANAGED_SNAPS; snapid = snap_seq = snap_seq + 1; } @@ -1570,7 +1573,13 @@ void pg_pool_t::encode(bufferlist& bl, uint64_t features) const ::encode(snaps, bl, features); ::encode(removed_snaps, bl); ::encode(auid, bl); - ::encode(flags, bl); + if (v >= 27) { + ::encode(flags, bl); + } else { + auto tmp = flags; + tmp &= ~(FLAG_SELFMANAGED_SNAPS | FLAG_POOL_SNAPS); + ::encode(tmp, bl); + } ::encode((uint32_t)0, bl); // crash_replay_interval ::encode(min_size, bl); ::encode(quota_max_bytes, bl); @@ -1662,6 +1671,14 @@ void pg_pool_t::decode(bufferlist::iterator& bl) } else { flags = 0; } + // upgrade path for selfmanaged vs pool snaps + if (snap_seq > 0 && (flags & (FLAG_SELFMANAGED_SNAPS|FLAG_POOL_SNAPS)) == 0) { + if (!removed_snaps.empty()) { + flags |= FLAG_SELFMANAGED_SNAPS; + } else { + flags |= FLAG_POOL_SNAPS; + } + } if (struct_v >= 7) { ::decode(min_size, bl); } else { @@ -1789,6 +1806,7 @@ void pg_pool_t::generate_test_instances(list& o) a.last_force_op_resend_preluminous = 123824; a.snap_seq = 10; a.snap_epoch = 11; + a.flags = FLAG_POOL_SNAPS; a.auid = 12; a.quota_max_bytes = 473; a.quota_max_objects = 474; @@ -1802,7 +1820,9 @@ void pg_pool_t::generate_test_instances(list& o) a.snaps[6].stamp = utime_t(23423, 4); o.push_back(new pg_pool_t(a)); - a.removed_snaps.insert(2); // not quite valid to combine with snaps! + a.flags = FLAG_SELFMANAGED_SNAPS; + a.snaps.clear(); + a.removed_snaps.insert(2); a.quota_max_bytes = 2473; a.quota_max_objects = 4374; a.tiers.insert(0); diff --git a/src/osd/osd_types.h b/src/osd/osd_types.h index 0951c29872a6a..74026843564a9 100644 --- a/src/osd/osd_types.h +++ b/src/osd/osd_types.h @@ -1157,6 +1157,8 @@ struct pg_pool_t { FLAG_FULL_QUOTA = 1<<10, // pool is currently running out of quota, will set FLAG_FULL too FLAG_NEARFULL = 1<<11, // pool is nearfull FLAG_BACKFILLFULL = 1<<12, // pool is backfillfull + FLAG_SELFMANAGED_SNAPS = 1<<13, // pool uses selfmanaged snaps + FLAG_POOL_SNAPS = 1<<14, // pool has pool snaps }; static const char *get_flag_name(int f) { @@ -1174,6 +1176,8 @@ struct pg_pool_t { case FLAG_FULL_QUOTA: return "full_quota"; case FLAG_NEARFULL: return "nearfull"; case FLAG_BACKFILLFULL: return "backfillfull"; + case FLAG_SELFMANAGED_SNAPS: return "selfmanaged_snaps"; + case FLAG_POOL_SNAPS: return "pool_snaps"; default: return "???"; } } @@ -1218,6 +1222,10 @@ struct pg_pool_t { return FLAG_NEARFULL; if (name == "backfillfull") return FLAG_BACKFILLFULL; + if (name == "selfmanaged_snaps") + return FLAG_SELFMANAGED_SNAPS; + if (name == "pool_snaps") + return FLAG_POOL_SNAPS; return 0; } -- 2.39.5