this);
ctx->op_t = pgbackend->get_transaction();
ctx->obc = obc;
+
+ if (!obc->obs.exists)
+ ctx->snapset_obc = get_object_context(obc->obs.oi.soid.get_snapdir(), false);
+
if (m->get_flags() & CEPH_OSD_FLAG_SKIPRWLOCKS) {
dout(20) << __func__ << ": skipping rw locks" << dendl;
} else if (m->get_flags() & CEPH_OSD_FLAG_FLUSH) {
if (ctx->new_obs.exists) {
if (!ctx->obs->exists) {
- // if we logically recreated the head, remove old _snapdir object
- hobject_t snapoid(soid.oid, soid.get_key(), CEPH_SNAPDIR, soid.hash,
- info.pgid.pool(), soid.get_namespace());
-
- ctx->snapset_obc = get_object_context(snapoid, false);
if (ctx->snapset_obc && ctx->snapset_obc->obs.exists) {
- bool got = ctx->snapset_obc->get_write(ctx->op);
- assert(got);
- ctx->release_snapset_obc = true;
+ hobject_t snapoid = soid.get_snapdir();
ctx->log.push_back(pg_log_entry_t(pg_log_entry_t::DELETE, snapoid,
ctx->at_version,
ctx->snapset_obc->obs.oi.version,
*/
bool get_rw_locks(OpContext *ctx) {
if (ctx->op->may_write() || ctx->op->may_cache()) {
- if (ctx->obc->get_write(ctx->op)) {
- ctx->lock_to_release = OpContext::W_LOCK;
+ /* If snapset_obc, !obc->obs->exists and we need to
+ * get a write lock on the snapdir as well as the
+ * head. Fortunately, we are guarranteed to get a
+ * write lock on the head if !obc->obs->exists
+ */
+ if (ctx->snapset_obc) {
+ assert(!ctx->obc->obs.exists);
+ if (ctx->snapset_obc->get_write(ctx->op)) {
+ ctx->release_snapset_obc = true;
+ ctx->lock_to_release = OpContext::W_LOCK;
+ } else {
+ return false;
+ }
+ // we are creating it and have the only ref
+ bool got = ctx->obc->get_write(ctx->op);
+ assert(got);
return true;
} else {
- return false;
+ if (ctx->obc->get_write(ctx->op)) {
+ ctx->lock_to_release = OpContext::W_LOCK;
+ return true;
+ } else {
+ return false;
+ }
}
} else {
assert(ctx->op->may_read());