From: Yehuda Sadeh Date: Tue, 27 Jan 2015 01:15:14 +0000 (-0800) Subject: rgw: fix a crash when getting ECANCELED in delete_obj() X-Git-Tag: v0.93~156^2~9 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=0ace0f5e34ef63571d4f8f0c0a2a287a057e9b60;p=ceph.git rgw: fix a crash when getting ECANCELED in delete_obj() bufferlist::c_str() returns NULL if bufferlist is empty. We were clearing the state, later on assigning s->obj_tag to a string. Signed-off-by: Yehuda Sadeh --- diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index b51bf1cf5456..eef205a252aa 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -3923,7 +3923,7 @@ int RGWRados::Object::complete_atomic_modification() chain.push_obj(bucket.data_pool, key, loc); } - string tag = state->obj_tag.c_str(); + string tag = (state->obj_tag.c_str() ? state->obj_tag.c_str() : ""); int ret = store->gc->send_chain(chain, tag, false); // do it async return ret; @@ -4204,6 +4204,8 @@ int RGWRados::Object::Delete::delete_obj() if (r < 0) return r; + uint64_t obj_size = state->size; + ObjectWriteOperation op; r = target->prepare_atomic_modification(op, false, NULL, NULL, NULL, true); @@ -4224,9 +4226,10 @@ int RGWRados::Object::Delete::delete_obj() store->remove_rgw_head_obj(op); r = ref.ioctx.operate(ref.oid, &op); + bool need_invalidate = false; if (r == -ECANCELED) { /* raced with another operation, we can regard it as removed */ - state->clear(); + need_invalidate = true; r = 0; } bool removed = (r >= 0); @@ -4248,16 +4251,18 @@ int RGWRados::Object::Delete::delete_obj() /* other than that, no need to propagate error */ } + if (need_invalidate) { + target->invalidate_state(); + } + if (r < 0) return r; if (ret_not_existed) return -ENOENT; - if (state) { - /* update quota cache */ - store->quota_handler->update_stats(params.bucket_owner, bucket, -1, 0, state->size); - } + /* update quota cache */ + store->quota_handler->update_stats(params.bucket_owner, bucket, -1, 0, obj_size); return 0; }