bool op_info_needs_init() const { return op_info.get_flags() == 0; }
bool check_rmw(int flag) const { return op_info.check_rmw(flag); }
bool may_read() const { return op_info.may_read(); }
+ bool may_read_data() const { return op_info.may_read_data(); }
bool may_write() const { return op_info.may_write(); }
bool may_cache() const { return op_info.may_cache(); }
bool rwordered_forced() const { return op_info.rwordered_forced(); }
* to get the second.
*/
if (write_ordered && ctx->op->may_read()) {
- ctx->lock_type = RWState::RWEXCL;
+ if (ctx->op->may_read_data()) {
+ ctx->lock_type = RWState::RWEXCL;
+ } else {
+ ctx->lock_type = RWState::RWWRITE;
+ }
} else if (write_ordered) {
ctx->lock_type = RWState::RWWRITE;
} else {
ceph_assert(rmw_flags != 0);
return rmw_flags & flag;
}
+// Returns true if op performs a read (including of the object_info).
bool OpInfo::may_read() const {
return need_read_cap() || check_rmw(CEPH_OSD_RMW_FLAG_CLASS_READ);
}
bool OpInfo::allows_returnvec() const {
return check_rmw(CEPH_OSD_RMW_FLAG_RETURNVEC);
}
+/**
+ * may_read_data()
+ *
+ * Returns true if op reads information other than the object_info. Requires that the
+ * osd flush any prior writes prior to servicing this op. Includes any information not
+ * cached by the osd in the object_info or snapset.
+ */
+bool OpInfo::may_read_data() const {
+ return check_rmw(CEPH_OSD_RMW_FLAG_READ_DATA);
+}
void OpInfo::set_rmw_flags(int flags) {
rmw_flags |= flags;
void OpInfo::set_skip_promote() { set_rmw_flags(CEPH_OSD_RMW_FLAG_SKIP_PROMOTE); }
void OpInfo::set_force_rwordered() { set_rmw_flags(CEPH_OSD_RMW_FLAG_RWORDERED); }
void OpInfo::set_returnvec() { set_rmw_flags(CEPH_OSD_RMW_FLAG_RETURNVEC); }
+void OpInfo::set_read_data() { set_rmw_flags(CEPH_OSD_RMW_FLAG_READ_DATA); }
int OpInfo::set_from_op(
if (ceph_osd_op_mode_modify(iter->op.op))
set_write();
}
- if (ceph_osd_op_mode_read(iter->op.op))
+ if (ceph_osd_op_mode_read(iter->op.op)) {
set_read();
+ if (iter->op.op != CEPH_OSD_OP_STAT) {
+ set_read_data();
+ }
+ }
// set READ flag if there are src_oids
if (iter->soid.oid.name.length())
// watch state (and may return early if the watch exists) or, in
// the case of ping, is simply a read op.
set_read();
+ set_read_data();
// fall through
case CEPH_OSD_OP_NOTIFY:
case CEPH_OSD_OP_NOTIFY_ACK:
CEPH_OSD_RMW_FLAG_SKIP_PROMOTE = (1 << 9),
CEPH_OSD_RMW_FLAG_RWORDERED = (1 << 10),
CEPH_OSD_RMW_FLAG_RETURNVEC = (1 << 11),
+ CEPH_OSD_RMW_FLAG_READ_DATA = (1 << 12),
};