#include "librbd/Operations.h"
#include "librbd/api/DiffIterate.h"
#include "librbd/api/Image.h"
+#include "librbd/api/Io.h"
#include "librbd/api/Migration.h"
#include "librbd/api/PoolMetadata.h"
#include "librbd/api/Snapshot.h"
#include "librbd/io/AioCompletion.h"
#include "librbd/io/ImageRequest.h"
-#include "librbd/io/ImageRequestWQ.h"
#include "osdc/Striper.h"
#include "common/Cond.h"
#include <boost/scope_exit.hpp>
void register_test_internal() {
}
+namespace librbd {
+
class TestInternal : public TestFixture {
public:
librbd::ImageCtx *ictx;
ASSERT_EQ(0, open_image(m_image_name, &ictx));
- ASSERT_EQ(0, lock_image(*ictx, LOCK_EXCLUSIVE, "manually locked"));
+ ASSERT_EQ(0, lock_image(*ictx, ClsLockType::EXCLUSIVE, "manually locked"));
librbd::NoOpProgressContext no_op;
ASSERT_EQ(-EROFS, ictx->operations->resize(m_image_size >> 1, true, no_op));
librbd::ImageCtx *ictx;
ASSERT_EQ(0, open_image(m_image_name, &ictx));
- ASSERT_EQ(0, lock_image(*ictx, LOCK_EXCLUSIVE, "manually locked"));
+ ASSERT_EQ(0, lock_image(*ictx, ClsLockType::EXCLUSIVE, "manually locked"));
ASSERT_EQ(-EROFS, snap_create(*ictx, "snap1"));
}
librbd::ImageCtx *ictx;
ASSERT_EQ(0, open_image(m_image_name, &ictx));
- ASSERT_EQ(0, lock_image(*ictx, LOCK_EXCLUSIVE, "manually locked"));
+ ASSERT_EQ(0, lock_image(*ictx, ClsLockType::EXCLUSIVE, "manually locked"));
librbd::NoOpProgressContext no_op;
ASSERT_EQ(-EROFS,
} BOOST_SCOPE_EXIT_END;
ASSERT_EQ(0, open_image(clone_name, &ictx2));
- ASSERT_EQ(0, lock_image(*ictx2, LOCK_EXCLUSIVE, "manually locked"));
+ ASSERT_EQ(0, lock_image(*ictx2, ClsLockType::EXCLUSIVE, "manually locked"));
librbd::NoOpProgressContext no_op;
ASSERT_EQ(-EROFS, ictx2->operations->flatten(no_op));
librbd::ImageCtx *ictx;
ASSERT_EQ(0, open_image(m_image_name, &ictx));
- ASSERT_EQ(0, lock_image(*ictx, LOCK_EXCLUSIVE, "manually locked"));
+ ASSERT_EQ(0, lock_image(*ictx, ClsLockType::EXCLUSIVE, "manually locked"));
std::string buffer(256, '1');
Context *ctx = new DummyContext();
bufferlist bl;
bl.append(buffer);
- ictx->io_work_queue->aio_write(c, 0, buffer.size(), std::move(bl), 0);
+ api::Io<>::aio_write(*ictx, c, 0, buffer.size(), std::move(bl), 0, true);
bool is_owner;
ASSERT_EQ(0, librbd::is_exclusive_lock_owner(ictx, &is_owner));
librbd::ImageCtx *ictx;
ASSERT_EQ(0, open_image(m_image_name, &ictx));
- ASSERT_EQ(0, lock_image(*ictx, LOCK_EXCLUSIVE, "manually locked"));
+ ASSERT_EQ(0, lock_image(*ictx, ClsLockType::EXCLUSIVE, "manually locked"));
Context *ctx = new DummyContext();
auto c = librbd::io::AioCompletion::create(ctx);
c->get();
- ictx->io_work_queue->aio_discard(c, 0, 256, false);
+ api::Io<>::aio_discard(*ictx, c, 0, 256, false, true);
bool is_owner;
ASSERT_EQ(0, librbd::is_exclusive_lock_owner(ictx, &is_owner));
map<string, bufferlist> pairs;
r = librbd::metadata_list(ictx, "", 0, &pairs);
ASSERT_EQ(0, r);
- ASSERT_EQ(5u, pairs.size());
+
+ uint8_t original_pairs_num = 0;
+ if (ictx->test_features(RBD_FEATURE_DIRTY_CACHE)) {
+ original_pairs_num = 1;
+ }
+ ASSERT_EQ(original_pairs_num + 5, pairs.size());
r = ictx->operations->metadata_remove("abcd");
ASSERT_EQ(0, r);
r = ictx->operations->metadata_remove("xyz");
pairs.clear();
r = librbd::metadata_list(ictx, "", 0, &pairs);
ASSERT_EQ(0, r);
- ASSERT_EQ(3u, pairs.size());
+ ASSERT_EQ(original_pairs_num + 3, pairs.size());
string val;
r = librbd::metadata_get(ictx, it->first, &val);
ASSERT_EQ(0, r);
bufferlist bl;
bl.append(std::string(256, '1'));
- ASSERT_EQ(256, ictx->io_work_queue->write(0, bl.length(), bufferlist{bl}, 0));
- ASSERT_EQ(256, ictx->io_work_queue->write(1024, bl.length(), bufferlist{bl},
- 0));
+ ASSERT_EQ(256, api::Io<>::write(*ictx, 0, bl.length(), bufferlist{bl}, 0));
+ ASSERT_EQ(256, api::Io<>::write(*ictx, 1024, bl.length(), bufferlist{bl},
+ 0));
ASSERT_EQ(0, snap_create(*ictx, "snap1"));
ASSERT_EQ(0,
ASSERT_EQ(0, snap_create(*ictx2, "snap1"));
ASSERT_EQ(0, snap_create(*ictx2, "snap2"));
- ASSERT_EQ(256, ictx2->io_work_queue->write(256, bl.length(), bufferlist{bl},
- 0));
+ ASSERT_EQ(256, api::Io<>::write(*ictx2, 256, bl.length(), bufferlist{bl},
+ 0));
+ ASSERT_EQ(0, flush_writeback_cache(ictx2));
librados::IoCtx snap_ctx;
snap_ctx.dup(ictx2->data_ctx);
snap_ctx.snap_set_read(CEPH_SNAPDIR);
ictx2, cls::rbd::UserSnapshotNamespace(), snap_name));
ASSERT_EQ(256,
- ictx2->io_work_queue->read(0, 256,
- librbd::io::ReadResult{read_result},
- 0));
+ api::Io<>::read(*ictx2, 0, 256,
+ librbd::io::ReadResult{read_result}, 0));
ASSERT_TRUE(bl.contents_equal(read_bl));
ASSERT_EQ(256,
- ictx2->io_work_queue->read(1024, 256,
- librbd::io::ReadResult{read_result},
- 0));
+ api::Io<>::read(*ictx2, 1024, 256,
+ librbd::io::ReadResult{read_result}, 0));
ASSERT_TRUE(bl.contents_equal(read_bl));
ASSERT_EQ(256,
- ictx2->io_work_queue->read(256, 256,
- librbd::io::ReadResult{read_result},
- 0));
+ api::Io<>::read(*ictx2, 256, 256,
+ librbd::io::ReadResult{read_result}, 0));
if (snap_name == NULL) {
ASSERT_TRUE(bl.contents_equal(read_bl));
} else {
BOOST_SCOPE_EXIT(ictx3) {
ictx3->state->close();
} BOOST_SCOPE_EXIT_END;
- std::map<uint64_t, uint64_t> expected_m;
+ std::vector<std::pair<uint64_t, uint64_t>> expected_m;
bufferlist expected_bl;
if (ictx3->enable_sparse_copyup && sparse_read_supported) {
if (snap_name == NULL) {
expected_bl.append(std::string(256 * 1, '1'));
}
}
- std::map<uint64_t, uint64_t> read_m;
+ std::vector<std::pair<uint64_t, uint64_t>> read_m;
librbd::io::ReadResult sparse_read_result{&read_m, &read_bl};
EXPECT_EQ(1024 + 256,
- ictx3->io_work_queue->read(0, 1024 + 256,
- librbd::io::ReadResult{sparse_read_result},
- 0));
+ api::Io<>::read(*ictx3, 0, 1024 + 256,
+ librbd::io::ReadResult{sparse_read_result}, 0));
EXPECT_EQ(expected_m, read_m);
EXPECT_TRUE(expected_bl.contents_equal(read_bl));
}
bufferlist bl;
bl.append(std::string(256, '1'));
- ASSERT_EQ(256, ictx2->io_work_queue->write(256, bl.length(), bufferlist{bl},
- 0));
+ ASSERT_EQ(256, api::Io<>::write(*ictx2, 256, bl.length(), bufferlist{bl}, 0));
+
+ ASSERT_EQ(0, flush_writeback_cache(ictx2));
librados::IoCtx snap_ctx;
snap_ctx.dup(ictx2->data_ctx);
ictx2, cls::rbd::UserSnapshotNamespace(), snap_name));
ASSERT_EQ(256,
- ictx2->io_work_queue->read(0, 256,
- librbd::io::ReadResult{read_result},
- 0));
+ api::Io<>::read(*ictx2, 0, 256,
+ librbd::io::ReadResult{read_result}, 0));
ASSERT_TRUE(read_bl.is_zero());
ASSERT_EQ(256,
- ictx2->io_work_queue->read(256, 256,
- librbd::io::ReadResult{read_result},
- 0));
+ api::Io<>::read(*ictx2, 256, 256,
+ librbd::io::ReadResult{read_result}, 0));
if (snap_name == NULL) {
ASSERT_TRUE(bl.contents_equal(read_bl));
} else {
bufferlist bl;
bl.append(std::string(256, '1'));
- ASSERT_EQ(256, ictx2->io_work_queue->write(256, bl.length(), bufferlist{bl},
- 0));
+ ASSERT_EQ(256, api::Io<>::write(*ictx2, 256, bl.length(), bufferlist{bl}, 0));
librados::IoCtx snap_ctx;
snap_ctx.dup(ictx2->data_ctx);
ictx2, cls::rbd::UserSnapshotNamespace(), snap_name));
ASSERT_EQ(256,
- ictx2->io_work_queue->read(0, 256,
- librbd::io::ReadResult{read_result},
- 0));
+ api::Io<>::read(*ictx2, 0, 256,
+ librbd::io::ReadResult{read_result}, 0));
ASSERT_TRUE(read_bl.is_zero());
ASSERT_EQ(256,
- ictx2->io_work_queue->read(256, 256,
- librbd::io::ReadResult{read_result},
- 0));
+ api::Io<>::read(*ictx2, 256, 256,
+ librbd::io::ReadResult{read_result}, 0));
if (snap_name == NULL) {
ASSERT_TRUE(bl.contents_equal(read_bl));
} else {
m_image_size = 1 << 14;
uint64_t features = 0;
- get_features(&features);
+ ::get_features(&features);
int order = 12;
ASSERT_EQ(0, m_rbd.create2(m_ioctx, m_image_name.c_str(), m_image_size,
features, &order));
bl.append(std::string(4096, '1'));
for (size_t i = 0; i < m_image_size; i += bl.length()) {
ASSERT_EQ((ssize_t)bl.length(),
- ictx->io_work_queue->write(i, bl.length(),
- bufferlist{bl}, 0));
+ api::Io<>::write(*ictx, i, bl.length(), bufferlist{bl}, 0));
}
ASSERT_EQ(0, snap_create(*ictx, "snap1"));
librbd::io::ReadResult read_result{&read_bl};
for (size_t i = 2 << order; i < m_image_size; i += bl.length()) {
ASSERT_EQ((ssize_t)bl.length(),
- ictx2->io_work_queue->read(i, bl.length(),
- librbd::io::ReadResult{read_result},
- 0));
+ api::Io<>::read(*ictx2, i, bl.length(),
+ librbd::io::ReadResult{read_result}, 0));
ASSERT_TRUE(bl.contents_equal(read_bl));
}
}
m_image_size = 1 << 14;
uint64_t features = 0;
- get_features(&features);
+ ::get_features(&features);
int order = 12;
ASSERT_EQ(0, m_rbd.create2(m_ioctx, m_image_name.c_str(), m_image_size,
features, &order));
bl.append(std::string(4096, '1'));
for (size_t i = 0; i < m_image_size; i += bl.length()) {
ASSERT_EQ((ssize_t)bl.length(),
- ictx->io_work_queue->write(i, bl.length(),
- bufferlist{bl}, 0));
+ api::Io<>::write(*ictx, i, bl.length(), bufferlist{bl}, 0));
}
ASSERT_EQ(0, snap_create(*ictx, "snap1"));
read_bl.push_back(read_ptr);
ASSERT_EQ(static_cast<int>(m_image_size - 64),
- ictx2->io_work_queue->discard(32, m_image_size - 64, false));
+ api::Io<>::discard(*ictx2, 32, m_image_size - 64, false));
ASSERT_EQ(0, librbd::api::Image<>::snap_set(ictx2,
cls::rbd::UserSnapshotNamespace(),
"snap1"));
librbd::io::ReadResult read_result{&read_bl};
for (size_t i = 0; i < m_image_size; i += bl.length()) {
ASSERT_EQ((ssize_t)bl.length(),
- ictx2->io_work_queue->read(i, bl.length(),
- librbd::io::ReadResult{read_result},
- 0));
+ api::Io<>::read(*ictx2, i, bl.length(),
+ librbd::io::ReadResult{read_result}, 0));
ASSERT_TRUE(bl.contents_equal(read_bl));
}
}
-TEST_F(TestInternal, ShrinkFlushesCache) {
- librbd::ImageCtx *ictx;
- ASSERT_EQ(0, open_image(m_image_name, &ictx));
-
- std::string buffer(4096, '1');
-
- // ensure write-path is initialized
- bufferlist write_bl;
- write_bl.append(buffer);
- ictx->io_work_queue->write(0, buffer.size(), bufferlist{write_bl}, 0);
-
- C_SaferCond cond_ctx;
- auto c = librbd::io::AioCompletion::create(&cond_ctx);
- c->get();
- ictx->io_work_queue->aio_write(c, 0, buffer.size(), bufferlist{write_bl}, 0);
-
- librbd::NoOpProgressContext no_op;
- ASSERT_EQ(0, ictx->operations->resize(m_image_size >> 1, true, no_op));
-
- ASSERT_TRUE(c->is_complete());
- ASSERT_EQ(0, c->wait_for_complete());
- ASSERT_EQ(0, cond_ctx.wait());
- c->put();
-}
-
TEST_F(TestInternal, ImageOptions) {
rbd_image_options_t opts1 = NULL, opts2 = NULL;
uint64_t uint64_val1 = 10, uint64_val2 = 0;
bufferlist bl;
bl.append(std::string(1 << ictx->order, '1'));
ASSERT_EQ((ssize_t)bl.length(),
- ictx->io_work_queue->write(0, bl.length(), bufferlist{bl}, 0));
- ASSERT_EQ(0, ictx->io_work_queue->flush());
+ api::Io<>::write(*ictx, 0, bl.length(), bufferlist{bl}, 0));
+ ASSERT_EQ(0, flush_writeback_cache(ictx));
ASSERT_EQ(0, create_snapshot("snap1", true));
ASSERT_EQ(0, open_image(clone_name, &ictx2));
ASSERT_EQ(0, ictx2->operations->snap_create(cls::rbd::UserSnapshotNamespace(),
- "snap1"));
+ "snap1", 0, no_op));
bufferlist write_full_bl;
write_full_bl.append(std::string(1 << ictx2->order, '2'));
ASSERT_EQ((ssize_t)write_full_bl.length(),
- ictx2->io_work_queue->write(0, write_full_bl.length(),
- bufferlist{write_full_bl}, 0));
+ api::Io<>::write(*ictx2, 0, write_full_bl.length(),
+ bufferlist{write_full_bl}, 0));
ASSERT_EQ(0, ictx2->operations->flatten(no_op));
librbd::io::ReadResult read_result{&read_bl};
ASSERT_EQ((ssize_t)read_bl.length(),
- ictx2->io_work_queue->read(0, read_bl.length(),
- librbd::io::ReadResult{read_result}, 0));
+ api::Io<>::read(*ictx2, 0, read_bl.length(),
+ librbd::io::ReadResult{read_result}, 0));
ASSERT_TRUE(write_full_bl.contents_equal(read_bl));
ASSERT_EQ(0, librbd::api::Image<>::snap_set(ictx2,
cls::rbd::UserSnapshotNamespace(),
"snap1"));
ASSERT_EQ((ssize_t)read_bl.length(),
- ictx2->io_work_queue->read(0, read_bl.length(),
- librbd::io::ReadResult{read_result}, 0));
+ api::Io<>::read(*ictx2, 0, read_bl.length(),
+ librbd::io::ReadResult{read_result}, 0));
ASSERT_TRUE(bl.contents_equal(read_bl));
}
int order = 12; // smallest object size is 4K
uint64_t features;
- ASSERT_TRUE(get_features(&features));
+ ASSERT_TRUE(::get_features(&features));
ASSERT_EQ(0, create_image_full_pp(m_rbd, m_ioctx, m_image_name, m_image_size,
features, false, &order));
int order = 12; // smallest object size is 4K
uint64_t features;
- ASSERT_TRUE(get_features(&features));
+ ASSERT_TRUE(::get_features(&features));
ASSERT_EQ(0, create_image_full_pp(m_rbd, m_ioctx, m_image_name, m_image_size,
features, false, &order));
ASSERT_EQ(TEST_IO_SIZE, image.write(itr->second, TEST_IO_SIZE, bl));
}
- ASSERT_EQ(0, image.flush());
+ ASSERT_EQ(0, image.close());
+ ASSERT_EQ(0, m_rbd.open(m_ioctx, image, m_image_name.c_str(), NULL));
bufferlist readbl;
printf("verify written data by reading\n");
std::string image_name = get_temp_image_name();
int order = 0;
uint64_t features;
- ASSERT_TRUE(get_features(&features));
+ ASSERT_TRUE(::get_features(&features));
ASSERT_EQ(0, create_image_full_pp(m_rbd, m_ioctx, image_name, m_image_size,
features, false, &order));
bl.append(std::string(4096, '\0'));
ASSERT_EQ((ssize_t)bl.length(),
- ictx->io_work_queue->write(0, bl.length(), bufferlist{bl}, 0));
+ api::Io<>::write(*ictx, 0, bl.length(), bufferlist{bl}, 0));
ASSERT_EQ((ssize_t)bl.length(),
- ictx->io_work_queue->write((1 << ictx->order) * 1 + 512,
- bl.length(), bufferlist{bl}, 0));
+ api::Io<>::write(*ictx, (1 << ictx->order) * 1 + 512,
+ bl.length(), bufferlist{bl}, 0));
bl.append(std::string(4096, '1'));
bl.append(std::string(4096, '\0'));
bl.append(std::string(4096, '2'));
bl.append(std::string(4096 - 1, '\0'));
ASSERT_EQ((ssize_t)bl.length(),
- ictx->io_work_queue->write((1 << ictx->order) * 10, bl.length(),
- bufferlist{bl}, 0));
+ api::Io<>::write(*ictx, (1 << ictx->order) * 10, bl.length(),
+ bufferlist{bl}, 0));
bufferlist bl2;
bl2.append(std::string(4096 - 1, '\0'));
ASSERT_EQ((ssize_t)bl2.length(),
- ictx->io_work_queue->write((1 << ictx->order) * 10 + 4096 * 10,
- bl2.length(), bufferlist{bl2}, 0));
+ api::Io<>::write(*ictx, (1 << ictx->order) * 10 + 4096 * 10,
+ bl2.length(), bufferlist{bl2}, 0));
- ASSERT_EQ(0, ictx->io_work_queue->flush());
+ ASSERT_EQ(0, flush_writeback_cache(ictx));
ASSERT_EQ(0, ictx->operations->sparsify(4096, no_op));
librbd::io::ReadResult read_result{&read_bl};
ASSERT_EQ((ssize_t)read_bl.length(),
- ictx->io_work_queue->read((1 << ictx->order) * 10, read_bl.length(),
- librbd::io::ReadResult{read_result}, 0));
+ api::Io<>::read(*ictx, (1 << ictx->order) * 10, read_bl.length(),
+ librbd::io::ReadResult{read_result}, 0));
ASSERT_TRUE(bl.contents_equal(read_bl));
std::string oid = ictx->get_object_name(0);
bl.append(std::string(4096, '\0'));
ASSERT_EQ((ssize_t)bl.length(),
- ictx->io_work_queue->write(0, bl.length(), bufferlist{bl}, 0));
+ api::Io<>::write(*ictx, 0, bl.length(), bufferlist{bl}, 0));
bl.append(std::string(4096, '1'));
bl.append(std::string(4096, '\0'));
bl.append(std::string(4096, '2'));
bl.append(std::string(4096, '\0'));
ASSERT_EQ((ssize_t)bl.length(),
- ictx->io_work_queue->write((1 << ictx->order) * 10, bl.length(),
- bufferlist{bl}, 0));
- ASSERT_EQ(0, ictx->io_work_queue->flush());
+ api::Io<>::write(*ictx, (1 << ictx->order) * 10, bl.length(),
+ bufferlist{bl}, 0));
+ ASSERT_EQ(0, flush_writeback_cache(ictx));
ASSERT_EQ(0, ictx->operations->sparsify(4096, no_op));
librbd::io::ReadResult read_result{&read_bl};
ASSERT_EQ((ssize_t)read_bl.length(),
- ictx->io_work_queue->read((1 << ictx->order) * 10, read_bl.length(),
- librbd::io::ReadResult{read_result}, 0));
+ api::Io<>::read(*ictx, (1 << ictx->order) * 10, read_bl.length(),
+ librbd::io::ReadResult{read_result}, 0));
ASSERT_TRUE(bl.contents_equal(read_bl));
std::string oid = ictx->get_object_name(0);
read_bl.push_back(read_ptr);
librbd::io::ReadResult read_result{&read_bl};
ASSERT_EQ(-ENODEV,
- ictx->io_work_queue->read(0, 256,
- librbd::io::ReadResult{read_result}, 0));
+ api::Io<>::read(*ictx, 0, 256,
+ librbd::io::ReadResult{read_result}, 0));
ASSERT_EQ(-ENODEV,
- ictx->io_work_queue->write(0, bl.length(), bufferlist{bl}, 0));
- ASSERT_EQ(-ENODEV, ictx->io_work_queue->discard(0, 1, 256));
+ api::Io<>::write(*ictx, 0, bl.length(), bufferlist{bl}, 0));
+ ASSERT_EQ(-ENODEV, api::Io<>::discard(*ictx, 0, 1, 256));
ASSERT_EQ(-ENODEV,
- ictx->io_work_queue->writesame(0, bl.length(), bufferlist{bl}, 0));
+ api::Io<>::write_same(*ictx, 0, bl.length(), bufferlist{bl}, 0));
uint64_t mismatch_off;
ASSERT_EQ(-ENODEV,
- ictx->io_work_queue->compare_and_write(0, bl.length(),
- bufferlist{bl},
- bufferlist{bl},
- &mismatch_off, 0));
- ASSERT_EQ(-ENODEV, ictx->io_work_queue->flush());
+ api::Io<>::compare_and_write(*ictx, 0, bl.length(),
+ bufferlist{bl}, bufferlist{bl},
+ &mismatch_off, 0));
+ ASSERT_EQ(-ENODEV, api::Io<>::flush(*ictx));
ASSERT_EQ(-ENODEV, snap_create(*ictx, "snap2"));
ASSERT_EQ(0, ictx->operations->snap_remove(cls::rbd::UserSnapshotNamespace(),
ASSERT_EQ(0, create_image_pp(m_rbd, m_ioctx, m_image_name, m_image_size));
}
+
+} // namespace librbd