Skip to content

Commit ffcd903

Browse files
committed
test/librbd: add TestInternal.FlattenInconsistentObjectMap
Inject an object map with all possible inconsistencies before flattening to ensure that something similar to commit 40af4f8 ("librbd: flatten operation should use object map") doesn't reappear in a different form. Signed-off-by: Ilya Dryomov <[email protected]>
1 parent 97ed3fc commit ffcd903

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

src/test/librbd/test_internal.cc

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,6 +1571,83 @@ TEST_F(TestInternal, FlattenNoEmptyObjects)
15711571
rados_ioctx_destroy(d_ioctx);
15721572
}
15731573

1574+
TEST_F(TestInternal, FlattenInconsistentObjectMap)
1575+
{
1576+
REQUIRE_FEATURE(RBD_FEATURE_LAYERING | RBD_FEATURE_OBJECT_MAP);
1577+
REQUIRE(!is_feature_enabled(RBD_FEATURE_STRIPINGV2));
1578+
1579+
librbd::ImageCtx* ictx;
1580+
ASSERT_EQ(0, open_image(m_image_name, &ictx));
1581+
1582+
librbd::NoOpProgressContext no_op;
1583+
ASSERT_EQ(0, ictx->operations->resize((1 << ictx->order) * 5, true, no_op));
1584+
1585+
bufferlist bl;
1586+
bl.append(std::string(256, '1'));
1587+
for (int i = 1; i < 5; i++) {
1588+
ASSERT_EQ(256, api::Io<>::write(*ictx, (1 << ictx->order) * i, 256,
1589+
bufferlist{bl}, 0));
1590+
}
1591+
1592+
ASSERT_EQ(0, snap_create(*ictx, "snap"));
1593+
ASSERT_EQ(0, snap_protect(*ictx, "snap"));
1594+
1595+
uint64_t features;
1596+
ASSERT_EQ(0, librbd::get_features(ictx, &features));
1597+
1598+
std::string clone_name = get_temp_image_name();
1599+
int order = ictx->order;
1600+
ASSERT_EQ(0, librbd::clone(m_ioctx, m_image_name.c_str(), "snap", m_ioctx,
1601+
clone_name.c_str(), features, &order, 0, 0));
1602+
1603+
close_image(ictx);
1604+
ASSERT_EQ(0, open_image(clone_name, &ictx));
1605+
1606+
C_SaferCond lock_ctx;
1607+
{
1608+
std::shared_lock owner_locker{ictx->owner_lock};
1609+
ictx->exclusive_lock->try_acquire_lock(&lock_ctx);
1610+
}
1611+
ASSERT_EQ(0, lock_ctx.wait());
1612+
ASSERT_TRUE(ictx->exclusive_lock->is_lock_owner());
1613+
1614+
ceph::BitVector<2> inconsistent_object_map;
1615+
inconsistent_object_map.resize(5);
1616+
inconsistent_object_map[0] = OBJECT_NONEXISTENT;
1617+
inconsistent_object_map[1] = OBJECT_NONEXISTENT;
1618+
inconsistent_object_map[2] = OBJECT_EXISTS;
1619+
inconsistent_object_map[3] = OBJECT_EXISTS_CLEAN;
1620+
// OBJECT_PENDING shouldn't happen within parent overlap, but test
1621+
// anyway
1622+
inconsistent_object_map[4] = OBJECT_PENDING;
1623+
1624+
auto object_map = new librbd::ObjectMap<>(*ictx, CEPH_NOSNAP);
1625+
C_SaferCond save_ctx;
1626+
{
1627+
std::shared_lock owner_locker{ictx->owner_lock};
1628+
std::unique_lock image_locker{ictx->image_lock};
1629+
object_map->set_object_map(inconsistent_object_map);
1630+
object_map->aio_save(&save_ctx);
1631+
}
1632+
ASSERT_EQ(0, save_ctx.wait());
1633+
object_map->put();
1634+
1635+
close_image(ictx);
1636+
ASSERT_EQ(0, open_image(clone_name, &ictx));
1637+
ASSERT_EQ(0, ictx->operations->flatten(no_op));
1638+
1639+
bufferptr read_ptr(256);
1640+
bufferlist read_bl;
1641+
read_bl.push_back(read_ptr);
1642+
1643+
librbd::io::ReadResult read_result{&read_bl};
1644+
for (int i = 1; i < 5; i++) {
1645+
ASSERT_EQ(256, api::Io<>::read(*ictx, (1 << ictx->order) * i, 256,
1646+
librbd::io::ReadResult{read_result}, 0));
1647+
EXPECT_TRUE(bl.contents_equal(read_bl));
1648+
}
1649+
}
1650+
15741651
TEST_F(TestInternal, PoolMetadataConfApply) {
15751652
REQUIRE_FORMAT_V2();
15761653

0 commit comments

Comments
 (0)