]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: reread obj meta on racing write operation
authorYehuda Sadeh <yehuda@hq.newdream.net>
Fri, 19 Aug 2011 06:35:25 +0000 (23:35 -0700)
committerYehuda Sadeh <yehuda@hq.newdream.net>
Fri, 19 Aug 2011 06:36:50 +0000 (23:36 -0700)
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h

index 9d3f9e586fcef65b6fc6187dd4a72fd49791cda6..f86322db69d3f1d7b1d517e23a512c36d9442afd 100644 (file)
@@ -832,12 +832,9 @@ int RGWRados::append_atomic_test(RGWRadosCtx *rctx, rgw_obj& obj, librados::IoCt
   return 0;
 }
 
-int RGWRados::prepare_atomic_for_write(RGWRadosCtx *rctx, rgw_obj& obj, librados::IoCtx& io_ctx,
+int RGWRados::prepare_atomic_for_write_impl(RGWRadosCtx *rctx, rgw_obj& obj, librados::IoCtx& io_ctx,
                             string& actual_obj, ObjectWriteOperation& op, RGWObjState **pstate)
 {
-  if (!rctx)
-    return 0;
-
   int r = get_obj_state(rctx, obj, io_ctx, actual_obj, pstate);
   if (r < 0)
     return r;
@@ -859,14 +856,14 @@ int RGWRados::prepare_atomic_for_write(RGWRadosCtx *rctx, rgw_obj& obj, librados
     else
       dest_obj.set_key(obj.object);
 
-    /* FIXME: clone obj should be conditional, should check src object id-tag */
     pair<string, bufferlist> cond(RGW_ATTR_ID_TAG, state->obj_tag);
     r = clone_obj_cond(NULL, dest_obj, 0, obj, 0, state->size, state->attrset, shadow_category, &state->mtime, &cond);
     if (r == -ECANCELED) {
       /* we lost in a race here, original object was replaced, we assume it was cloned
          as required */
       RGW_LOG(0) << "clone_obj_cond was cancelled, lost in a race" << dendl;
-      r = 0;
+      state->clear();
+      return r;
     } else {
       int ret = rctx->notify_intent(dest_obj, DEL_OBJ);
       if (ret < 0) {
@@ -897,6 +894,18 @@ int RGWRados::prepare_atomic_for_write(RGWRadosCtx *rctx, rgw_obj& obj, librados
   return 0;
 }
 
+int RGWRados::prepare_atomic_for_write(RGWRadosCtx *rctx, rgw_obj& obj, librados::IoCtx& io_ctx,
+                            string& actual_obj, ObjectWriteOperation& op, RGWObjState **pstate)
+{
+  if (!rctx)
+    return 0;
+
+  int r;
+  do {
+    r = prepare_atomic_for_write_impl(rctx, obj, io_ctx, actual_obj, op, pstate);
+  } while (r == -ECANCELED);
+}
+
 /**
  * Set an attr on an object.
  * bucket: name of the bucket holding the object
index 8e794ff9e6e67724781805fc0861eeeb4cab7c1c..847d2d1fab63921e939d6845ce339c3f18885408 100644 (file)
@@ -27,6 +27,16 @@ struct RGWObjState {
     }
     return false;
   }
+
+  void clear() {
+    has_attrs = false;
+    exists = false;
+    size = 0;
+    mtime = 0;
+    obj_tag.clear();
+    shadow_obj.clear();
+    attrset.clear();
+  }
 };
 
 struct RGWRadosCtx {
@@ -75,6 +85,8 @@ class RGWRados  : public RGWAccess
   int get_obj_state(RGWRadosCtx *rctx, rgw_obj& obj, librados::IoCtx& io_ctx, string& actual_obj, RGWObjState **state);
   int append_atomic_test(RGWRadosCtx *rctx, rgw_obj& obj, librados::IoCtx& io_ctx,
                          string& actual_obj, librados::ObjectOperation& op, RGWObjState **state);
+  int prepare_atomic_for_write_impl(RGWRadosCtx *rctx, rgw_obj& obj, librados::IoCtx& io_ctx,
+                         string& actual_obj, librados::ObjectWriteOperation& op, RGWObjState **pstate);
   int prepare_atomic_for_write(RGWRadosCtx *rctx, rgw_obj& obj, librados::IoCtx& io_ctx,
                          string& actual_obj, librados::ObjectWriteOperation& op, RGWObjState **pstate);
 public: