]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
ECTransaction: adjacent extents might have unaligned boundaries
authorSamuel Just <sjust@redhat.com>
Tue, 22 Nov 2016 23:54:37 +0000 (15:54 -0800)
committerSamuel Just <sjust@redhat.com>
Thu, 24 Nov 2016 00:47:16 +0000 (16:47 -0800)
Signed-off-by: Samuel Just <sjust@redhat.com>
src/include/interval_set.h
src/osd/ECTransaction.h

index 4108f1dd082a37f53e4bdb8f105dfcf9bd7d3ce2..f01c61cda5626fe96dc0fee04e5e4c19387eed2b 100644 (file)
@@ -499,6 +499,11 @@ class interval_set {
     swap(a);    
     union_of(a, b);
   }
+  void union_insert(T off, T len) {
+    interval_set a;
+    a.insert(off, len);
+    union_of(a);
+  }
 
   bool subset_of(const interval_set &big) const {
     for (typename std::map<T,T>::const_iterator i = m.begin();
index a60b39c5a8112ebe820cef02c2d8771e6dccbec3..c0665bf36c2d239675dd51cd3a5c8e111f0cff7d 100644 (file)
@@ -73,13 +73,13 @@ namespace ECTransaction {
            i.second.truncate->first < projected_size) {
          if (!(sinfo.logical_offset_is_stripe_aligned(
                  i.second.truncate->first))) {
-           plan.to_read[i.first].insert(
+           plan.to_read[i.first].union_insert(
              sinfo.logical_to_prev_stripe_offset(i.second.truncate->first),
              sinfo.get_stripe_width());
 
            ldpp_dout(dpp, 20) << __func__ << ": unaligned truncate" << dendl;
 
-           will_write.insert(
+           will_write.union_insert(
              sinfo.logical_to_prev_stripe_offset(i.second.truncate->first),
              sinfo.get_stripe_width());
          }
@@ -87,6 +87,7 @@ namespace ECTransaction {
            i.second.truncate->first);
        }
 
+       extent_set raw_write_set;
        for (auto &&extent: i.second.buffer_updates) {
          using BufferUpdate = PGTransaction::ObjectOperation::BufferUpdate;
          if (boost::get<BufferUpdate::CloneRange>(&(extent.get_val()))) {
@@ -94,11 +95,16 @@ namespace ECTransaction {
              0 ==
              "CloneRange is not allowed, do_op should have returned ENOTSUPP");
          }
+         raw_write_set.insert(extent.get_off(), extent.get_len());
+       }
 
+       for (auto extent = raw_write_set.begin();
+            extent != raw_write_set.end();
+            ++extent) {
          uint64_t head_start =
-           sinfo.logical_to_prev_stripe_offset(extent.get_off());
+           sinfo.logical_to_prev_stripe_offset(extent.get_start());
          uint64_t head_finish =
-           sinfo.logical_to_next_stripe_offset(extent.get_off());
+           sinfo.logical_to_next_stripe_offset(extent.get_start());
          if (head_start > projected_size) {
            head_start = projected_size;
          }
@@ -106,22 +112,22 @@ namespace ECTransaction {
              head_start < projected_size) {
            assert(head_finish <= projected_size);
            assert(head_finish - head_start == sinfo.get_stripe_width());
-           plan.to_read[i.first].insert(
+           plan.to_read[i.first].union_insert(
              head_start, sinfo.get_stripe_width());
          }
 
          uint64_t tail_start =
            sinfo.logical_to_prev_stripe_offset(
-             extent.get_off() + extent.get_len());
+             extent.get_start() + extent.get_len());
          uint64_t tail_finish =
            sinfo.logical_to_next_stripe_offset(
-             extent.get_off() + extent.get_len());
+             extent.get_start() + extent.get_len());
          if (tail_start != tail_finish &&
              (head_start == head_finish || tail_start != head_start) &&
              tail_start < projected_size) {
            assert(tail_finish <= projected_size);
            assert(tail_finish - tail_start == sinfo.get_stripe_width());
-           plan.to_read[i.first].insert(
+           plan.to_read[i.first].union_insert(
              tail_start, sinfo.get_stripe_width());
          }
 
@@ -130,7 +136,7 @@ namespace ECTransaction {
              sinfo.logical_offset_is_stripe_aligned(
                tail_finish - head_start)
              );
-           will_write.insert(
+           will_write.union_insert(
              head_start, tail_finish - head_start);
            if (tail_finish > projected_size)
              projected_size = tail_finish;
@@ -146,7 +152,7 @@ namespace ECTransaction {
          ldpp_dout(dpp, 20) << __func__ << ": truncating out to "
                             <<  truncating_to
                             << dendl;
-         will_write.insert(projected_size, truncating_to - projected_size);
+         will_write.union_insert(projected_size, truncating_to - projected_size);
          projected_size = truncating_to;
        }