]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd/osd_types: pg_pool_t: add FLAG_{SELFMANAGED,POOL}_SNAPS flags
authorSage Weil <sage@redhat.com>
Fri, 13 Oct 2017 15:39:51 +0000 (10:39 -0500)
committerSage Weil <sage@redhat.com>
Sat, 2 Dec 2017 03:26:49 +0000 (21:26 -0600)
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 <sage@redhat.com>
src/osd/osd_types.cc
src/osd/osd_types.h

index 6cd18c2ef6fa967ac687de811d889764c6a3af84..2e56f8dbeebcd4bc2bc44fc5157137b9f0aeb3a8 100644 (file)
@@ -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<pg_pool_t*>& 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<pg_pool_t*>& 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);
index 0951c29872a6a1cc7fd2672ae8706ac16ce88245..74026843564a957dbdfe34150c66316afb6e02f4 100644 (file)
@@ -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;
   }