From: Samuel Just Date: Mon, 17 Mar 2014 19:30:52 +0000 (-0700) Subject: ReplicatedPG: disallow trans which atomically create and remove an object X-Git-Tag: v0.78~2^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=9ee108428176c93fe48ae5ae95b160eadabca9b6;p=ceph.git ReplicatedPG: disallow trans which atomically create and remove an object There are a few problems with such a transaction: 1) We don't really have a way to represent it in the log 2) How does it affect snaps? 3) In finish_ctx, it means we cannot assume that if we are saving snaps on a snapdir we must be creating the snapdir. For now, we'll just disallow such a transaction. Signed-off-by: Samuel Just --- diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index 160f0d654cf0..352bf0bd84d1 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -4944,6 +4944,12 @@ int ReplicatedPG::prepare_transaction(OpContext *ctx) return result; } + if (!ctx->new_obs.exists && !ctx->obs->exists) { + // We can't really represent in the log an operation which atomically + // creates and removes an object + return -EINVAL; + } + // cache: clear whiteout? if (pool.info.cache_mode == pg_pool_t::CACHEMODE_WRITEBACK) { if (ctx->user_modify && @@ -5012,6 +5018,9 @@ void ReplicatedPG::finish_ctx(OpContext *ctx, int log_op_type) } } } else if (ctx->new_snapset.clones.size()) { + // see do_op, if !new_obs.exist && !obs->exists, we returned EINVAL already + assert(ctx->obs->exists); + // save snapset on _snap hobject_t snapoid(soid.oid, soid.get_key(), CEPH_SNAPDIR, soid.hash, info.pgid.pool(), soid.get_namespace());