From: Kefu Chai Date: Wed, 29 Sep 2021 14:54:15 +0000 (+0800) Subject: Merge pull request #42353 from ifed01/wip-ifed-fix-invalid-offset-repair X-Git-Tag: v17.1.0~784 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=710fded6e280fce73fd214da4ab26928831133ef;p=ceph.git Merge pull request #42353 from ifed01/wip-ifed-fix-invalid-offset-repair os/bluestore: fix writing to invalid offset when repairing Reviewed-by: Adam Kupczyk --- 710fded6e280fce73fd214da4ab26928831133ef diff --cc src/test/objectstore/test_bluestore_types.cc index c8a62a12527,50935f6a9b9..8d5efbf4f8f --- a/src/test/objectstore/test_bluestore_types.cc +++ b/src/test/objectstore/test_bluestore_types.cc @@@ -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 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);