#define CEPH_OSD_OP_MODE_WR 0x2000
#define CEPH_OSD_OP_MODE_RMW 0x3000
#define CEPH_OSD_OP_MODE_SUB 0x4000
+#define CEPH_OSD_OP_MODE_CACHE 0x8000
#define CEPH_OSD_OP_TYPE 0x0f00
#define CEPH_OSD_OP_TYPE_LOCK 0x0100
{
return op & CEPH_OSD_OP_MODE_WR;
}
+static inline int ceph_osd_op_mode_cache(int op)
+{
+ return op & CEPH_OSD_OP_MODE_CACHE;
+}
/*
* note that the following tmap stuff is also defined in the ceph librados.h
if (ceph_osd_op_type_pg(iter->op.op))
op->set_pg_op();
+ if (ceph_osd_op_mode_cache(iter->op.op))
+ op->set_cache();
+
switch (iter->op.op) {
case CEPH_OSD_OP_CALL:
{
}
bool OpRequest::may_read() { return need_read_cap() || need_class_read_cap(); }
bool OpRequest::may_write() { return need_write_cap() || need_class_write_cap(); }
+bool OpRequest::may_cache() { return check_rmw(CEPH_OSD_RMW_FLAG_CACHE); }
bool OpRequest::includes_pg_op() { return check_rmw(CEPH_OSD_RMW_FLAG_PGOP); }
bool OpRequest::need_read_cap() {
return check_rmw(CEPH_OSD_RMW_FLAG_READ);
void OpRequest::set_class_read() { rmw_flags |= CEPH_OSD_RMW_FLAG_CLASS_READ; }
void OpRequest::set_class_write() { rmw_flags |= CEPH_OSD_RMW_FLAG_CLASS_WRITE; }
void OpRequest::set_pg_op() { rmw_flags |= CEPH_OSD_RMW_FLAG_PGOP; }
+void OpRequest::set_cache() { rmw_flags |= CEPH_OSD_RMW_FLAG_CACHE; }
bool check_rmw(int flag);
bool may_read();
bool may_write();
+ bool may_cache();
bool includes_pg_op();
bool need_read_cap();
bool need_write_cap();
bool need_class_write_cap();
void set_read();
void set_write();
+ void set_cache();
void set_class_read();
void set_class_write();
void set_pg_op();
if (OSD::op_is_discardable(m)) {
dout(20) << " discard " << *m << dendl;
return true;
- } else if (op->may_write() &&
+ } else if ((op->may_write() || op->may_cache()) &&
(!is_primary() ||
!same_for_modify_since(m->get_map_epoch()))) {
osd->handle_misdirected_op(this, op);
}
// order this op as a write?
- bool write_ordered = op->may_write() || (m->get_flags() & CEPH_OSD_FLAG_RWORDERED);
+ bool write_ordered =
+ op->may_write() ||
+ op->may_cache() ||
+ (m->get_flags() & CEPH_OSD_FLAG_RWORDERED);
dout(10) << "do_op " << *m
<< (op->may_write() ? " may_write" : "")
<< (op->may_read() ? " may_read" : "")
+ << (op->may_cache() ? " may_cache" : "")
<< " -> " << (write_ordered ? "write-ordered" : "read-ordered")
<< " flags " << ceph_osd_flag_string(m->get_flags())
<< dendl;
}
ObjectContextRef obc;
- bool can_create = op->may_write();
+ bool can_create = op->may_write() || op->may_cache();
hobject_t missing_oid;
hobject_t oid(m->get_oid(),
m->get_object_locator().key,
osd->reply_op_error(op, -ENFILE);
return;
}
- if (!op->may_write() && (!obc->obs.exists ||
- obc->obs.oi.is_whiteout())) {
+ if (!op->may_write() && !op->may_cache() && (!obc->obs.exists ||
+ obc->obs.oi.is_whiteout())) {
close_op_ctx(ctx);
osd->reply_op_error(op, -ENOENT);
return;
ctx->op_t = ObjectStore::Transaction();
ctx->local_t = ObjectStore::Transaction();
- // dup/replay?
- if (op->may_write()) {
+ if (op->may_write() || op->may_cache()) {
+ // dup/replay?
const pg_log_entry_t *entry = pg_log.get_log().get_request(ctx->reqid);
if (entry) {
const eversion_t& oldv = entry->version;
ctx->reply->set_reply_versions(ctx->at_version, ctx->user_at_version);
- assert(op->may_write());
+ assert(op->may_write() || op->may_cache());
// trim log?
calc_trim_to();
osd->logger->inc(l_osd_op_r);
osd->logger->inc(l_osd_op_r_outb, outb);
osd->logger->tinc(l_osd_op_r_lat, latency);
- } else if (op->may_write()) {
+ } else if (op->may_write() || op->may_cache()) {
osd->logger->inc(l_osd_op_w);
osd->logger->inc(l_osd_op_w_inb, inb);
osd->logger->tinc(l_osd_op_w_rlat, rlatency);
* @return true on success, false if we are queued
*/
bool get_rw_locks(OpContext *ctx) {
- if (ctx->op->may_write()) {
+ if (ctx->op->may_write() || ctx->op->may_cache()) {
if (ctx->obc->get_write(ctx->op)) {
ctx->lock_to_release = OpContext::W_LOCK;
return true;
CEPH_OSD_RMW_FLAG_CLASS_READ = (1 << 3),
CEPH_OSD_RMW_FLAG_CLASS_WRITE = (1 << 4),
CEPH_OSD_RMW_FLAG_PGOP = (1 << 5),
+ CEPH_OSD_RMW_FLAG_CACHE = (1 << 6),
};