]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: generate new tag for object when setting object attrs
authorYehuda Sadeh <yehuda@redhat.com>
Fri, 27 Mar 2015 23:32:48 +0000 (16:32 -0700)
committerYehuda Sadeh <yehuda@redhat.com>
Fri, 27 Mar 2015 23:34:50 +0000 (16:34 -0700)
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 <yehuda@redhat.com>
src/rgw/rgw_rados.cc

index 52f8a701f2dd135e8a8ba4ef773acacfe3b132fc..1e2cce141a48fe1188fdaee502c1424f14611282 100644 (file)
@@ -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);