bool is_fresh_object() const {
return boost::get<Init::None>(&init_type) == nullptr;
}
+ bool is_rename() const {
+ return boost::get<Init::Rename>(&init_type) != nullptr;
+ }
bool has_source(hobject_t *source = nullptr) const {
return match(
init_type,
op.init_type = ObjectOperation::Init::Rename{source};
}
- /// Remove
+ /// Remove -- must not be called on rename target
void remove(
const hobject_t &hoid ///< [in] obj to remove
) {
auto &op = get_object_op_for_modify(hoid);
- assert(!op.updated_snaps);
- op = ObjectOperation();
- op.delete_first = true;
+ if (!op.is_fresh_object()) {
+ assert(!op.updated_snaps);
+ op = ObjectOperation();
+ op.delete_first = true;
+ } else {
+ assert(!op.is_rename());
+ op_map.erase(hoid); // make it a noop if it's a fresh object
+ }
}
void update_snaps(
}
if (ctx->update_log_only) {
+ if (result >= 0)
+ do_osd_op_effects(ctx, m->get_connection());
+
dout(20) << __func__ << " update_log_only -- result=" << result << dendl;
- assert(result < 0);
// save just what we need from ctx
MOSDOpReply *reply = ctx->reply;
ctx->reply = nullptr;
return result;
}
- // read-op? done?
+ // read-op? write-op noop? done?
if (ctx->op_t->empty() && !ctx->modify) {
unstable_stats.add(ctx->delta_stats);
+ if (ctx->op->may_write() &&
+ get_osdmap()->test_flag(CEPH_OSDMAP_REQUIRE_KRAKEN)) {
+ ctx->update_log_only = true;
+ }
return result;
}