From: Yehuda Sadeh Date: Fri, 27 Mar 2015 23:32:48 +0000 (-0700) Subject: rgw: generate new tag for object when setting object attrs X-Git-Tag: v0.80.10~19^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=7538319dd7aa80a3318c108d345dee8044cf20a8;p=ceph.git rgw: generate new tag for object when setting object attrs Fixes: #11256 Backport: firefly, hammer Beforehand we were reusing the object's tag, which is problematic as this tag is used for bucket index updates, and we might be clobbering a racing update (like object removal). Signed-off-by: Yehuda Sadeh --- diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 52f8a701f2d..1e2cce141a4 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -4162,10 +4162,18 @@ int RGWRados::set_attrs(void *ctx, rgw_obj& obj, return 0; string tag; + bufferlist bl; if (state) { - r = prepare_update_index(state, bucket, CLS_RGW_OP_ADD, obj, tag); + /* we don't pass state here, because we need to generate a new tag, not reuse the + * same tag, otherwise we might race and clobber another operation on the same object + */ + r = prepare_update_index(NULL, bucket, CLS_RGW_OP_ADD, obj, tag); if (r < 0) return r; + + bl.append(tag.c_str(), tag.size() + 1); + + op.setxattr(RGW_ATTR_ID_TAG, bl); } r = ref.ioctx.operate(ref.oid, &op); @@ -4192,6 +4200,7 @@ int RGWRados::set_attrs(void *ctx, rgw_obj& obj, return r; if (state) { + state->obj_tag.swap(bl); if (rmattrs) { for (iter = rmattrs->begin(); iter != rmattrs->end(); ++iter) { state->attrset.erase(iter->first);