mirror of
https://github.com/ceph/ceph
synced 2025-03-20 09:16:59 +00:00
Merge pull request #7617 from liewegas/wip-14745
osd: fix forced prmootion for CALL ops Reviewed-by: Sage Weil <sage@redhat.com>
This commit is contained in:
commit
48d007f659
@ -2147,11 +2147,13 @@ ReplicatedPG::cache_result_t ReplicatedPG::maybe_handle_cache_detail(
|
||||
return cache_result_t::BLOCKED_FULL;
|
||||
}
|
||||
|
||||
if (!hit_set && (must_promote || !op->need_skip_promote()) ) {
|
||||
if (must_promote || (!hit_set && !op->need_skip_promote())) {
|
||||
promote_object(obc, missing_oid, oloc, op, promote_obc);
|
||||
return cache_result_t::BLOCKED_PROMOTE;
|
||||
} else if (op->may_write() || op->may_cache()) {
|
||||
if (can_proxy_write && !must_promote) {
|
||||
}
|
||||
|
||||
if (op->may_write() || op->may_cache()) {
|
||||
if (can_proxy_write) {
|
||||
do_proxy_write(op, missing_oid);
|
||||
} else {
|
||||
// promote if can't proxy the write
|
||||
@ -2170,7 +2172,7 @@ ReplicatedPG::cache_result_t ReplicatedPG::maybe_handle_cache_detail(
|
||||
return cache_result_t::HANDLED_PROXY;
|
||||
} else {
|
||||
bool did_proxy_read = false;
|
||||
if (can_proxy_read && !must_promote) {
|
||||
if (can_proxy_read) {
|
||||
do_proxy_read(op);
|
||||
did_proxy_read = true;
|
||||
} else {
|
||||
@ -2228,7 +2230,7 @@ ReplicatedPG::cache_result_t ReplicatedPG::maybe_handle_cache_detail(
|
||||
|
||||
case pg_pool_t::CACHEMODE_READFORWARD:
|
||||
// Do writeback to the cache tier for writes
|
||||
if (op->may_write() || write_ordered) {
|
||||
if (op->may_write() || write_ordered || must_promote) {
|
||||
if (agent_state &&
|
||||
agent_state->evict_mode == TierAgentState::EVICT_MODE_FULL) {
|
||||
dout(20) << __func__ << " cache pool full, waiting" << dendl;
|
||||
@ -2245,7 +2247,7 @@ ReplicatedPG::cache_result_t ReplicatedPG::maybe_handle_cache_detail(
|
||||
|
||||
case pg_pool_t::CACHEMODE_READPROXY:
|
||||
// Do writeback to the cache tier for writes
|
||||
if (op->may_write() || write_ordered) {
|
||||
if (op->may_write() || write_ordered || must_promote) {
|
||||
if (agent_state &&
|
||||
agent_state->evict_mode == TierAgentState::EVICT_MODE_FULL) {
|
||||
dout(20) << __func__ << " cache pool full, waiting" << dendl;
|
||||
|
@ -4637,6 +4637,122 @@ TEST_F(LibRadosTwoPoolsECPP, TryFlushReadRace) {
|
||||
test_lock.Unlock();
|
||||
}
|
||||
|
||||
TEST_F(LibRadosTierECPP, CallForcesPromote) {
|
||||
Rados cluster;
|
||||
std::string pool_name = get_temp_pool_name();
|
||||
std::string cache_pool_name = pool_name + "-cache";
|
||||
ASSERT_EQ("", create_one_ec_pool_pp(pool_name, cluster));
|
||||
ASSERT_EQ(0, cluster.pool_create(cache_pool_name.c_str()));
|
||||
IoCtx cache_ioctx;
|
||||
ASSERT_EQ(0, cluster.ioctx_create(cache_pool_name.c_str(), cache_ioctx));
|
||||
IoCtx ioctx;
|
||||
ASSERT_EQ(0, cluster.ioctx_create(pool_name.c_str(), ioctx));
|
||||
|
||||
// configure cache
|
||||
bufferlist inbl;
|
||||
ASSERT_EQ(0, cluster.mon_command(
|
||||
"{\"prefix\": \"osd tier add\", \"pool\": \"" + pool_name +
|
||||
"\", \"tierpool\": \"" + cache_pool_name + "\"}",
|
||||
inbl, NULL, NULL));
|
||||
ASSERT_EQ(0, cluster.mon_command(
|
||||
"{\"prefix\": \"osd tier set-overlay\", \"pool\": \"" + pool_name +
|
||||
"\", \"overlaypool\": \"" + cache_pool_name + "\"}",
|
||||
inbl, NULL, NULL));
|
||||
ASSERT_EQ(0, cluster.mon_command(
|
||||
"{\"prefix\": \"osd tier cache-mode\", \"pool\": \"" + cache_pool_name +
|
||||
"\", \"mode\": \"writeback\"}",
|
||||
inbl, NULL, NULL));
|
||||
|
||||
// set things up such that the op would normally be proxied
|
||||
ASSERT_EQ(0, cluster.mon_command(
|
||||
set_pool_str(cache_pool_name, "hit_set_count", 2),
|
||||
inbl, NULL, NULL));
|
||||
ASSERT_EQ(0, cluster.mon_command(
|
||||
set_pool_str(cache_pool_name, "hit_set_period", 600),
|
||||
inbl, NULL, NULL));
|
||||
ASSERT_EQ(0, cluster.mon_command(
|
||||
set_pool_str(cache_pool_name, "hit_set_type",
|
||||
"explicit_object"),
|
||||
inbl, NULL, NULL));
|
||||
ASSERT_EQ(0, cluster.mon_command(
|
||||
set_pool_str(cache_pool_name, "min_read_recency_for_promote",
|
||||
"4"),
|
||||
inbl, NULL, NULL));
|
||||
|
||||
// wait for maps to settle
|
||||
cluster.wait_for_latest_osdmap();
|
||||
|
||||
// create/dirty object
|
||||
bufferlist bl;
|
||||
bl.append("hi there");
|
||||
{
|
||||
ObjectWriteOperation op;
|
||||
op.write_full(bl);
|
||||
ASSERT_EQ(0, ioctx.operate("foo", &op));
|
||||
}
|
||||
|
||||
// flush
|
||||
{
|
||||
ObjectReadOperation op;
|
||||
op.cache_flush();
|
||||
librados::AioCompletion *completion = cluster.aio_create_completion();
|
||||
ASSERT_EQ(0, cache_ioctx.aio_operate(
|
||||
"foo", completion, &op,
|
||||
librados::OPERATION_IGNORE_OVERLAY, NULL));
|
||||
completion->wait_for_safe();
|
||||
ASSERT_EQ(0, completion->get_return_value());
|
||||
completion->release();
|
||||
}
|
||||
|
||||
// evict
|
||||
{
|
||||
ObjectReadOperation op;
|
||||
op.cache_evict();
|
||||
librados::AioCompletion *completion = cluster.aio_create_completion();
|
||||
ASSERT_EQ(0, cache_ioctx.aio_operate("foo", completion, &op,
|
||||
librados::OPERATION_IGNORE_CACHE,
|
||||
NULL));
|
||||
completion->wait_for_safe();
|
||||
ASSERT_EQ(0, completion->get_return_value());
|
||||
completion->release();
|
||||
}
|
||||
|
||||
// call
|
||||
{
|
||||
ObjectReadOperation op;
|
||||
bufferlist bl;
|
||||
op.exec("rbd", "get_id", bl);
|
||||
bufferlist out;
|
||||
// should get EIO (not an rbd object), not -EOPNOTSUPP (we didn't promote)
|
||||
ASSERT_EQ(-5, ioctx.operate("foo", &op, &out));
|
||||
}
|
||||
|
||||
// make sure foo is back in the cache tier
|
||||
{
|
||||
NObjectIterator it = cache_ioctx.nobjects_begin();
|
||||
ASSERT_TRUE(it != cache_ioctx.nobjects_end());
|
||||
ASSERT_TRUE(it->get_oid() == string("foo"));
|
||||
++it;
|
||||
ASSERT_TRUE(it == cache_ioctx.nobjects_end());
|
||||
}
|
||||
|
||||
// tear down tiers
|
||||
ASSERT_EQ(0, cluster.mon_command(
|
||||
"{\"prefix\": \"osd tier remove-overlay\", \"pool\": \"" + pool_name +
|
||||
"\"}",
|
||||
inbl, NULL, NULL));
|
||||
ASSERT_EQ(0, cluster.mon_command(
|
||||
"{\"prefix\": \"osd tier remove\", \"pool\": \"" + pool_name +
|
||||
"\", \"tierpool\": \"" + cache_pool_name + "\"}",
|
||||
inbl, NULL, NULL));
|
||||
|
||||
// wait for maps to settle before next test
|
||||
cluster.wait_for_latest_osdmap();
|
||||
|
||||
ASSERT_EQ(0, cluster.pool_delete(cache_pool_name.c_str()));
|
||||
ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster));
|
||||
}
|
||||
|
||||
TEST_F(LibRadosTierECPP, HitSetNone) {
|
||||
{
|
||||
list< pair<time_t,time_t> > ls;
|
||||
|
Loading…
Reference in New Issue
Block a user