osd: add 'proxy' cache mode

The 'forward' mode is flawed for the same reason that redirects
are flawed: they allow the reordering of requests.  Add a proxy
mode that can be used instead of forward.  (Later we can consider
dropping forward entirely?)

Fixes: #12814
Signed-off-by: Sage Weil <sage@redhat.com>
This commit is contained in:
Sage Weil 2016-03-21 22:48:12 -04:00
parent 7f441b1065
commit d7da68848a
4 changed files with 49 additions and 7 deletions

View File

@ -795,7 +795,7 @@ COMMAND("osd tier rm " \
"osd", "rw", "cli,rest")
COMMAND("osd tier cache-mode " \
"name=pool,type=CephPoolname " \
"name=mode,type=CephChoices,strings=none|writeback|forward|readonly|readforward|readproxy", \
"name=mode,type=CephChoices,strings=none|writeback|forward|readonly|readforward|proxy|readproxy", \
"specify the caching mode for cache tier <pool>", "osd", "rw", "cli,rest")
COMMAND("osd tier set-overlay " \
"name=pool,type=CephPoolname " \

View File

@ -7313,15 +7313,17 @@ done:
* writeback: Cache writes, promote reads from base pool
* readonly: Forward writes to base pool
* readforward: Writes are in writeback mode, Reads are in forward mode
* proxy: Proxy all reads and writes to base pool
* readproxy: Writes are in writeback mode, Reads are in proxy mode
*
* Hence, these are the allowed transitions:
*
* none -> any
* forward -> readforward || readproxy || writeback || any IF num_objects_dirty == 0
* readforward -> forward || readproxy || writeback || any IF num_objects_dirty == 0
* readproxy -> forward || readforward || writeback || any IF num_objects_dirty == 0
* writeback -> readforward || readproxy || forward
* forward -> proxy || readforward || readproxy || writeback || any IF num_objects_dirty == 0
* proxy -> forward || readforward || readproxy || writeback || any IF num_objects_dirty == 0
* readforward -> forward || proxy || readproxy || writeback || any IF num_objects_dirty == 0
* readproxy -> forward || proxy || readforward || writeback || any IF num_objects_dirty == 0
* writeback -> readforward || readproxy || forward || proxy
* readonly -> any
*/
@ -7331,6 +7333,7 @@ done:
if (p->cache_mode == pg_pool_t::CACHEMODE_WRITEBACK &&
(mode != pg_pool_t::CACHEMODE_FORWARD &&
mode != pg_pool_t::CACHEMODE_PROXY &&
mode != pg_pool_t::CACHEMODE_READFORWARD &&
mode != pg_pool_t::CACHEMODE_READPROXY)) {
ss << "unable to set cache-mode '" << pg_pool_t::get_cache_mode_name(mode)
@ -7338,6 +7341,8 @@ done:
<< "' pool; only '"
<< pg_pool_t::get_cache_mode_name(pg_pool_t::CACHEMODE_FORWARD)
<< "','"
<< pg_pool_t::get_cache_mode_name(pg_pool_t::CACHEMODE_PROXY)
<< "','"
<< pg_pool_t::get_cache_mode_name(pg_pool_t::CACHEMODE_READFORWARD)
<< "','"
<< pg_pool_t::get_cache_mode_name(pg_pool_t::CACHEMODE_READPROXY)
@ -7348,16 +7353,25 @@ done:
if ((p->cache_mode == pg_pool_t::CACHEMODE_READFORWARD &&
(mode != pg_pool_t::CACHEMODE_WRITEBACK &&
mode != pg_pool_t::CACHEMODE_FORWARD &&
mode != pg_pool_t::CACHEMODE_PROXY &&
mode != pg_pool_t::CACHEMODE_READPROXY)) ||
(p->cache_mode == pg_pool_t::CACHEMODE_READPROXY &&
(mode != pg_pool_t::CACHEMODE_WRITEBACK &&
mode != pg_pool_t::CACHEMODE_FORWARD &&
mode != pg_pool_t::CACHEMODE_READFORWARD)) ||
mode != pg_pool_t::CACHEMODE_READFORWARD &&
mode != pg_pool_t::CACHEMODE_PROXY)) ||
(p->cache_mode == pg_pool_t::CACHEMODE_PROXY &&
(mode != pg_pool_t::CACHEMODE_WRITEBACK &&
mode != pg_pool_t::CACHEMODE_FORWARD &&
mode != pg_pool_t::CACHEMODE_READFORWARD &&
mode != pg_pool_t::CACHEMODE_READPROXY)) ||
(p->cache_mode == pg_pool_t::CACHEMODE_FORWARD &&
(mode != pg_pool_t::CACHEMODE_WRITEBACK &&
mode != pg_pool_t::CACHEMODE_READFORWARD &&
mode != pg_pool_t::CACHEMODE_PROXY &&
mode != pg_pool_t::CACHEMODE_READPROXY))) {
const pool_stat_t& tier_stats =

View File

@ -2255,6 +2255,7 @@ ReplicatedPG::cache_result_t ReplicatedPG::maybe_handle_cache_detail(
return cache_result_t::NOOP;
case pg_pool_t::CACHEMODE_FORWARD:
// FIXME: this mode allows requests to be reordered.
do_cache_redirect(op);
return cache_result_t::HANDLED_REDIRECT;
@ -2289,6 +2290,28 @@ ReplicatedPG::cache_result_t ReplicatedPG::maybe_handle_cache_detail(
do_cache_redirect(op);
return cache_result_t::HANDLED_REDIRECT;
case pg_pool_t::CACHEMODE_PROXY:
if (!must_promote) {
if (op->may_write() || op->may_cache() || write_ordered) {
if (can_proxy_write) {
do_proxy_write(op, missing_oid);
return cache_result_t::HANDLED_PROXY;
}
} else {
do_proxy_read(op);
return cache_result_t::HANDLED_PROXY;
}
}
// ugh, we're forced to promote.
if (agent_state &&
agent_state->evict_mode == TierAgentState::EVICT_MODE_FULL) {
dout(20) << __func__ << " cache pool full, waiting" << dendl;
block_write_on_full_cache(missing_oid, op);
return cache_result_t::BLOCKED_FULL;
}
promote_object(obc, missing_oid, oloc, op, promote_obc);
return cache_result_t::BLOCKED_PROMOTE;
case pg_pool_t::CACHEMODE_READPROXY:
// Do writeback to the cache tier for writes
if (op->may_write() || write_ordered || must_promote) {

View File

@ -1125,7 +1125,8 @@ struct pg_pool_t {
CACHEMODE_FORWARD = 2, ///< forward if not in cache
CACHEMODE_READONLY = 3, ///< handle reads, forward writes [not strongly consistent]
CACHEMODE_READFORWARD = 4, ///< forward reads, write to cache flush later
CACHEMODE_READPROXY = 5 ///< proxy reads, write to cache flush later
CACHEMODE_READPROXY = 5, ///< proxy reads, write to cache flush later
CACHEMODE_PROXY = 6, ///< proxy if not in cache
} cache_mode_t;
static const char *get_cache_mode_name(cache_mode_t m) {
switch (m) {
@ -1135,6 +1136,7 @@ struct pg_pool_t {
case CACHEMODE_READONLY: return "readonly";
case CACHEMODE_READFORWARD: return "readforward";
case CACHEMODE_READPROXY: return "readproxy";
case CACHEMODE_PROXY: return "proxy";
default: return "unknown";
}
}
@ -1151,6 +1153,8 @@ struct pg_pool_t {
return CACHEMODE_READFORWARD;
if (s == "readproxy")
return CACHEMODE_READPROXY;
if (s == "proxy")
return CACHEMODE_PROXY;
return (cache_mode_t)-1;
}
const char *get_cache_mode_name() const {
@ -1161,6 +1165,7 @@ struct pg_pool_t {
case CACHEMODE_NONE:
case CACHEMODE_FORWARD:
case CACHEMODE_READONLY:
case CACHEMODE_PROXY:
return false;
case CACHEMODE_WRITEBACK:
case CACHEMODE_READFORWARD: