]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: isolate GC stuff to be able to cover it with UT
authorIgor Fedotov <ifedotov@mirantis.com>
Wed, 12 Oct 2016 16:13:00 +0000 (19:13 +0300)
committerIgor Fedotov <ifedotov@mirantis.com>
Fri, 14 Oct 2016 12:29:25 +0000 (12:29 +0000)
Signed-off-by: Igor Fedotov <ifedotov@mirantis.com>
src/os/bluestore/BlueStore.cc
src/os/bluestore/BlueStore.h

index e75ab1f4145deab57f378aa4aa1ab09a570b29b8..f1f02419e23548e063ff6074e06fd8a04773e0dd 100644 (file)
@@ -2149,6 +2149,83 @@ BlueStore::BlobRef BlueStore::ExtentMap::split_blob(
   return rb;
 }
 
+bool BlueStore::ExtentMap::do_write_check_depth(
+  uint64_t onode_size,
+  uint64_t start_offset,
+  uint64_t end_offset,
+  uint8_t  *blob_depth,
+  uint64_t *gc_start_offset,
+  uint64_t *gc_end_offset)
+{
+  uint8_t depth = 0;
+  bool head_overlap = false;
+  bool tail_overlap = false;
+
+  *gc_start_offset = start_offset;
+  *gc_end_offset = end_offset;
+  *blob_depth = 1;
+
+  auto hp = seek_lextent(start_offset);
+  if (hp != extent_map.end() &&
+    hp->logical_offset < start_offset &&
+    start_offset < hp->logical_offset + hp->length) {
+    depth = hp->blob_depth;
+    head_overlap = true;
+  }
+
+  auto tp = seek_lextent(end_offset);
+  if (tp != extent_map.end() &&
+    tp->logical_offset < end_offset &&
+    end_offset < tp->logical_offset + tp->length) {
+    tail_overlap = true;
+    if (depth < tp->blob_depth) {
+      depth = tp->blob_depth;
+    }
+  }
+
+  if (depth >= g_conf->bluestore_gc_max_blob_depth) {
+    if (head_overlap) {
+      auto hp_next = hp;
+      while (hp != extent_map.begin() && hp->blob_depth > 1) {
+       hp_next = hp;
+       --hp;
+       if (hp->logical_offset + hp->length != hp_next->logical_offset) {
+         hp = hp_next;
+         break;
+       }
+      }
+      *gc_start_offset = hp->logical_offset;
+    }
+    if (tail_overlap) {
+      auto tp_prev = tp;
+
+      while (tp->blob_depth > 1) {
+       tp_prev = tp;
+       tp++;
+       if (tp == extent_map.end() ||
+         (tp_prev->logical_offset + tp_prev->length) != tp->logical_offset) {
+         tp = tp_prev;
+         break;
+       }
+      }
+      *gc_end_offset = tp->logical_offset + tp_prev->length;
+    }
+  }
+  if (*gc_end_offset > onode_size) {
+    *gc_end_offset = MAX(end_offset, onode_size);
+  }
+
+  bool do_collect = true;
+  if (depth < g_conf->bluestore_gc_max_blob_depth) {
+    *blob_depth = 1 + depth;
+    do_collect = false;;
+  }
+  dout(20) << __func__ << " GC depth " << (int)*blob_depth
+           << ", gc 0x" << std::hex << *gc_start_offset << "~"
+           << (*gc_end_offset - *gc_start_offset)
+           << std::dec << dendl;
+  return do_collect;
+}
 
 // Onode
 
@@ -2164,8 +2241,6 @@ void BlueStore::Onode::flush()
   dout(20) << __func__ << " done" << dendl;
 }
 
-
-
 // =======================================================
 
 // Collection
@@ -2310,8 +2385,6 @@ void BlueStore::Collection::trim_cache()
     g_conf->bluestore_buffer_cache_size / store->cache_shards.size());
 }
 
-
-
 // =======================================================
 
 #undef dout_prefix
@@ -7632,83 +7705,6 @@ void BlueStore::_wctx_finish(
   }
 }
 
-bool BlueStore::_do_write_check_depth(
-  OnodeRef o,
-  uint64_t start_offset,
-  uint64_t end_offset,
-  uint8_t  *blob_depth,
-  uint64_t *gc_start_offset,
-  uint64_t *gc_end_offset)
-{
-  uint8_t depth = 0;
-  bool head_overlap = false;
-  bool tail_overlap = false;
-
-  *gc_start_offset = start_offset;
-  *gc_end_offset   = end_offset;
-  *blob_depth = 1;
-
-  auto hp = o->extent_map.seek_lextent(start_offset);
-  if (hp != o->extent_map.extent_map.end() &&
-      hp->logical_offset < start_offset &&
-      start_offset < hp->logical_offset + hp->length) {
-    depth = hp->blob_depth;
-    head_overlap = true;
-  }
-  
-  auto tp = o->extent_map.seek_lextent(end_offset);
-  if (tp != o->extent_map.extent_map.end() &&
-      tp->logical_offset < end_offset &&
-    end_offset < tp->logical_offset + tp->length) {
-    tail_overlap = true;
-    if (depth < tp->blob_depth) {
-      depth = tp->blob_depth;
-    }
-  }
-
-  if (depth >= g_conf->bluestore_gc_max_blob_depth) {
-    if (head_overlap) {
-      auto hp_next = hp;
-      while (hp != o->extent_map.extent_map.begin() && hp->blob_depth > 1) {
-        hp_next = hp;
-        --hp;
-        if (hp->logical_offset + hp->length != hp_next->logical_offset) {
-          hp = hp_next;
-          break;
-        }
-      }
-      *gc_start_offset = hp->logical_offset;
-    }
-    if (tail_overlap) {
-      auto tp_prev = tp;
-
-      while (tp->blob_depth > 1) {
-        tp_prev = tp;
-        tp++;
-        if (tp == o->extent_map.extent_map.end() ||
-            (tp_prev->logical_offset + tp_prev->length) != tp->logical_offset) {
-          tp = tp_prev;
-          break;
-        }
-      }
-      *gc_end_offset = tp->logical_offset + tp_prev->length;
-    }
-  }
-  if (*gc_end_offset > o->onode.size) {
-    *gc_end_offset = MAX(end_offset, o->onode.size);
-  }
-  dout(20) << __func__ << " depth " << (int)depth
-          << ", gc 0x" << std::hex << *gc_start_offset << "~"
-          << (*gc_end_offset - *gc_start_offset)
-          << std::dec << dendl;
-  if (depth >= g_conf->bluestore_gc_max_blob_depth) {
-    return true;
-  } else {
-    *blob_depth = 1 + depth;
-    return false;
-  }
-}
-
 void BlueStore::_do_write_data(
   TransContext *txc,
   CollectionRef& c,
@@ -7836,8 +7832,12 @@ int BlueStore::_do_write(
           << std::dec << dendl;
 
   uint64_t gc_start_offset = offset, gc_end_offset = end;
-  if (_do_write_check_depth(o, offset, end, &wctx.blob_depth,
-                            &gc_start_offset, &gc_end_offset)) {
+  bool do_collect = 
+    o->extent_map.do_write_check_depth(o->extent_map, o->onode.size,
+                                       offset, end, &wctx.blob_depth,
+                                       &gc_start_offset,
+                                      &gc_end_offset);
+  if (do_collect) {
     // we need garbage collection of blobs.
     if (offset > gc_start_offset) {
       bufferlist head_bl;
index 689b37939a38620a23857bc6e814e2b507b48d79..50dd2343fa57855cc2a8011c1ba4279cff2d03ec 100644 (file)
@@ -690,6 +690,14 @@ public:
 
     /// split a blob (and referring extents)
     BlobRef split_blob(BlobRef lb, uint32_t blob_offset, uint32_t pos);
+
+    bool do_write_check_depth(
+      uint64_t onode_size,
+      uint64_t start_offset,
+      uint64_t end_offset,
+      uint8_t  *blob_depth,
+      uint64_t *gc_start_offset,
+      uint64_t *gc_end_offset);
   };
 
   struct OnodeSpace;
@@ -735,6 +743,7 @@ public:
   };
   typedef boost::intrusive_ptr<Onode> OnodeRef;
 
+
   /// a cache (shard) of onodes and buffers
   struct Cache {
     PerfCounters *logger;
@@ -1873,14 +1882,6 @@ private:
   void _pad_zeros(bufferlist *bl, uint64_t *offset,
                  uint64_t chunk_size);
 
-  bool _do_write_check_depth(
-    OnodeRef o,
-    uint64_t start_offset,
-    uint64_t end_offset,
-    uint8_t  *blob_depth,
-    uint64_t *gc_start_offset,
-    uint64_t *gc_end_offset);
-
   int _do_write(TransContext *txc,
                CollectionRef &c,
                OnodeRef o,