]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: fix clone dirty_range again 16994/head
authorSage Weil <sage@redhat.com>
Fri, 11 Aug 2017 16:46:09 +0000 (12:46 -0400)
committerSage Weil <sage@redhat.com>
Fri, 11 Aug 2017 16:46:25 +0000 (12:46 -0400)
If we are cloning a blob for a 1 byte logical extent then dirty_range_begin
will equal _end and we won't dirty the source onode (with possibly newly
shared blobs).

Fix by using a separate flag to indicate whether we are dirtying instead
of overloading the begin/end markers for this.  Note that even if they
are equal dirty_range will still dirty the shard in question.

This is a result of 0ae5d92d42500e5ab08253a00bda47b957767ebc.

Fixes: http://tracker.ceph.com/issues/20983
Signed-off-by: Sage Weil <sage@redhat.com>
src/os/bluestore/BlueStore.cc

index 40e152bcce9751959d2d3fad3d7252dcedd93b73..3a179c4c5fc19302524c0514140611ad1627bc41 100644 (file)
@@ -10916,6 +10916,7 @@ int BlueStore::_do_clone_range(
   uint64_t end = srcoff + length;
   uint32_t dirty_range_begin = 0;
   uint32_t dirty_range_end = 0;
+  bool src_dirty = false;
   for (auto ep = oldo->extent_map.seek_lextent(srcoff);
        ep != oldo->extent_map.extent_map.end();
        ++ep) {
@@ -10936,7 +10937,8 @@ int BlueStore::_do_clone_range(
       // make sure it is shared
       if (!blob.is_shared()) {
        c->make_blob_shared(_assign_blobid(txc), e.blob);
-       if (dirty_range_begin == 0 && dirty_range_end == 0) {
+       if (!src_dirty) {
+         src_dirty = true;
           dirty_range_begin = e.logical_offset;
         }
         assert(e.logical_end() > 0);
@@ -10988,7 +10990,7 @@ int BlueStore::_do_clone_range(
     dout(20) << __func__ << "  dst " << *ne << dendl;
     ++n;
   }
-  if (dirty_range_end > dirty_range_begin) {
+  if (src_dirty) {
     oldo->extent_map.dirty_range(dirty_range_begin,
       dirty_range_end - dirty_range_begin);
     txc->write_onode(oldo);