]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
Merge pull request #42353 from ifed01/wip-ifed-fix-invalid-offset-repair
authorKefu Chai <kchai@redhat.com>
Wed, 29 Sep 2021 14:54:15 +0000 (22:54 +0800)
committerGitHub <noreply@github.com>
Wed, 29 Sep 2021 14:54:15 +0000 (22:54 +0800)
os/bluestore: fix writing to invalid offset when repairing

Reviewed-by: Adam Kupczyk <akupczyk@redhat.com>
1  2 
src/os/bluestore/BlueStore.cc
src/test/objectstore/test_bluestore_types.cc

Simple merge
index c8a62a125276b2b06187944b8ce599db2e171c4b,50935f6a9b95cd50d359d2dfb2b9edb8bb2063c5..8d5efbf4f8fcd862c42bded8a4531e77e753eef8
@@@ -1689,9 -1687,59 +1689,58 @@@ TEST(bluestore_blob_t, unused
      ASSERT_TRUE(b.is_unused(end0_aligned, min_alloc_size * 3 - end0_aligned));
    }
  }
+ // This UT is primarily intended to show how repair procedure
+ // causes erroneous write to INVALID_OFFSET which is reported in
+ // https://tracker.ceph.com/issues/51682
+ // Basic map_any functionality is tested as well though.
+ //
+ TEST(bluestore_blob_t, wrong_map_bl_in_51682)
+ {
+   {
+     bluestore_blob_t b;
+     uint64_t min_alloc_size = 4 << 10; // 64 kB
+     b.allocated_test(bluestore_pextent_t(0x17ba000, 4 * min_alloc_size));
+     b.allocated_test(bluestore_pextent_t(0x17bf000, 4 * min_alloc_size));
+     b.allocated_test(
+       bluestore_pextent_t(
+         bluestore_pextent_t::INVALID_OFFSET,
+         1 * min_alloc_size));
+     b.allocated_test(bluestore_pextent_t(0x153c44d000, 7 * min_alloc_size));
+     b.mark_used(0, 0x8000);
+     b.mark_used(0x9000, 0x7000);
+     string s(0x7000, 'a');
+     bufferlist bl;
+     bl.append(s);
+     const size_t num_expected_entries = 5;
+     uint64_t expected[num_expected_entries][2] = {
+       {0x17ba000, 0x4000},
+       {0x17bf000, 0x3000},
+       {0x17c0000, 0x3000},
+       {0xffffffffffffffff, 0x1000},
+       {0x153c44d000, 0x3000}};
+     size_t expected_pos = 0;
+     b.map_bl(0, bl,
+       [&](uint64_t o, bufferlist& bl) {
+         ASSERT_EQ(o, expected[expected_pos][0]);
+         ASSERT_EQ(bl.length(), expected[expected_pos][1]);
+         ++expected_pos;
+       });
+     // 0x5000 is an improper offset presumably provided when doing a repair
+     b.map_bl(0x5000, bl,
+       [&](uint64_t o, bufferlist& bl) {
+         ASSERT_EQ(o, expected[expected_pos][0]);
+         ASSERT_EQ(bl.length(), expected[expected_pos][1]);
+         ++expected_pos;
+       });
+     ASSERT_EQ(expected_pos, num_expected_entries);
+   }
+ }
  
  int main(int argc, char **argv) {
 -  vector<const char*> args;
 -  argv_to_vec(argc, (const char **)argv, args);
 +  auto args = argv_to_vec(argc, argv);
    auto cct = global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT,
                         CODE_ENVIRONMENT_UTILITY,
                         CINIT_FLAG_NO_DEFAULT_CONFIG_FILE);