Flush puts us in an conundrum:
- the flush eventually writes, behaving like a write
- writes take the write lock at the start
- to flush, we send copy-from to the base pool, which does a copy-get on
our object
- the copy-get is a read, that blocks on the write.
This flag will allow an op to skip the initial locking step. It will need
to take it later, of course.
Signed-off-by: Sage Weil <sage@inktank.com>
Conflicts:
src/osd/ReplicatedPG.cc
CEPH_OSD_FLAG_LOCALIZE_READS = 0x2000, /* read from nearby replica, if any */
CEPH_OSD_FLAG_RWORDERED = 0x4000, /* order wrt concurrent reads */
CEPH_OSD_FLAG_IGNORE_OVERLAY = 0x8000, /* ignore pool overlay */
+ CEPH_OSD_FLAG_SKIPRWLOCKS = 0x10000, /* skip rw locks */
};
enum {
OPERATION_LOCALIZE_READS = 2,
OPERATION_ORDER_READS_WRITES = 4,
OPERATION_IGNORE_OVERLAY = 8,
+ OPERATION_SKIPRWLOCKS = 16,
};
/*
op_flags |= CEPH_OSD_FLAG_RWORDERED;
if (flags & librados::OPERATION_IGNORE_OVERLAY)
op_flags |= CEPH_OSD_FLAG_IGNORE_OVERLAY;
+ if (flags & librados::OPERATION_SKIPRWLOCKS)
+ op_flags |= CEPH_OSD_FLAG_SKIPRWLOCKS;
return op_flags;
}
&obc->obs, obc->ssc,
this);
ctx->obc = obc;
- if (!get_rw_locks(ctx)) {
+ if (m->get_flags() & CEPH_OSD_FLAG_SKIPRWLOCKS) {
+ dout(20) << __func__ << ": skipping rw locks" << dendl;
+ } else if (!get_rw_locks(ctx)) {
op->mark_delayed("waiting for rw locks");
close_op_ctx(ctx);
return;
case CEPH_OSD_FLAG_LOCALIZE_READS: return "localize_reads";
case CEPH_OSD_FLAG_RWORDERED: return "rwordered";
case CEPH_OSD_FLAG_IGNORE_OVERLAY: return "ignore_overlay";
+ case CEPH_OSD_FLAG_SKIPRWLOCKS: return "skiprwlocks";
default: return "???";
}
}