"osd", "rw", "cli,rest")
COMMAND("osd tier cache-mode " \
"name=pool,type=CephPoolname " \
- "name=mode,type=CephChoices,strings=none|writeback|forward|readonly|readforward", \
+ "name=mode,type=CephChoices,strings=none|writeback|forward|readonly|readforward|readproxy", \
"specify the caching mode for cache tier <pool>", "osd", "rw", "cli,rest")
COMMAND("osd tier set-overlay " \
"name=pool,type=CephPoolname " \
* forward: Forward all reads and writes to base pool
* writeback: Cache writes, promote reads from base pool
* readonly: Forward writes to base pool
- * readforward: Writes are in writeback mode, Reads and in forward mode
+ * readforward: Writes are in writeback mode, Reads are in forward mode
+ * readproxy: Writes are in writeback mode, Reads are in proxy mode
*
* Hence, these are the allowed transitions:
*
* none -> any
- * forward -> readforward || writeback || any IF num_objects_dirty == 0
- * readforward -> forward || writeback || any IF num_objects_dirty == 0
- * writeback -> readforward || forward
+ * 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
* readonly -> any
*/
if (p->cache_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_READPROXY)) {
ss << "unable to set cache-mode '" << pg_pool_t::get_cache_mode_name(mode)
<< "' on a '" << pg_pool_t::get_cache_mode_name(p->cache_mode)
<< "' 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_READFORWARD)
+ << "','"
+ << pg_pool_t::get_cache_mode_name(pg_pool_t::CACHEMODE_READPROXY)
<< "' allowed.";
err = -EINVAL;
goto reply;
}
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_FORWARD &&
+ 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)) ||
(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_READFORWARD &&
+ mode != pg_pool_t::CACHEMODE_READPROXY))) {
const pool_stat_t& tier_stats =
mon->pgmon()->pg_map.get_pg_pool_sum_stat(pool_id);
do_cache_redirect(op, obc);
return true;
+ case pg_pool_t::CACHEMODE_READPROXY:
+ // Do writeback to the cache tier for writes
+ if (op->may_write() || write_ordered) {
+ if (agent_state &&
+ agent_state->evict_mode == TierAgentState::EVICT_MODE_FULL) {
+ dout(20) << __func__ << " cache pool full, waiting" << dendl;
+ waiting_for_cache_not_full.push_back(op);
+ return true;
+ }
+ if (can_skip_promote(op, obc)) {
+ return false;
+ }
+ promote_object(obc, missing_oid, oloc, op);
+ return true;
+ }
+
+ // If it is a read, we can read, we need to proxy it
+ do_proxy_read(op);
+ return true;
+
default:
assert(0 == "unrecognized cache_mode");
}
CACHEMODE_WRITEBACK = 1, ///< write to cache, flush later
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_READFORWARD = 4, ///< forward reads, write to cache flush later
+ CACHEMODE_READPROXY = 5 ///< proxy reads, write to cache flush later
} cache_mode_t;
static const char *get_cache_mode_name(cache_mode_t m) {
switch (m) {
case CACHEMODE_FORWARD: return "forward";
case CACHEMODE_READONLY: return "readonly";
case CACHEMODE_READFORWARD: return "readforward";
+ case CACHEMODE_READPROXY: return "readproxy";
default: return "unknown";
}
}
return CACHEMODE_READONLY;
if (s == "readforward")
return CACHEMODE_READFORWARD;
+ if (s == "readproxy")
+ return CACHEMODE_READPROXY;
return (cache_mode_t)-1;
}
const char *get_cache_mode_name() const {
return false;
case CACHEMODE_WRITEBACK:
case CACHEMODE_READFORWARD:
+ case CACHEMODE_READPROXY:
return true;
default:
assert(0 == "implement me");
'toomany']))
def test_tier_cache_mode(self):
- for mode in ('none', 'writeback', 'forward', 'readonly', 'readforward'):
+ for mode in ('none', 'writeback', 'forward', 'readonly', 'readforward', 'readproxy'):
self.assert_valid_command(['osd', 'tier', 'cache-mode',
'poolname', mode])
assert_equal({}, validate_command(sigdict, ['osd', 'tier',