]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: fix ECANCELED handling in rgw_get_system_obj()
authorYehuda Sadeh <yehuda@redhat.com>
Tue, 22 Nov 2016 18:33:12 +0000 (10:33 -0800)
committerYehuda Sadeh <yehuda@redhat.com>
Thu, 9 Mar 2017 17:18:53 +0000 (09:18 -0800)
Fixes: http://tracker.ceph.com/issues/17996
Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
src/cls/version/cls_version_types.h
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h
src/rgw/rgw_tools.cc

index 4b77e5dd26d3c2c2c07dbd1b3cec0dabc9cf6b5f..22ae0779ea308b718f86903cea6a142aeb2b4014 100644 (file)
@@ -31,6 +31,11 @@ struct obj_version {
     ver++;
   }
 
+  void clear() {
+    ver = 0;
+    tag.clear();
+  }
+
   bool empty() {
     return tag.empty();
   }
index 553201b2fca872787e2cbc60d106a68ce160d0e4..a4d86866bbe1d75dba8bbf520a329891e6b4d41a 100644 (file)
@@ -8907,6 +8907,11 @@ void RGWRados::Object::invalidate_state()
   ctx.obj.invalidate(obj);
 }
 
+void RGWRados::SystemObject::invalidate_state()
+{
+  ctx.raw.invalidate(obj);
+}
+
 int RGWRados::Object::prepare_atomic_modification(ObjectWriteOperation& op, bool reset_obj, const string *ptag,
                                                   const char *if_match, const char *if_nomatch, bool removal_op)
 {
index dfb04c7db4c4c9769d1e31085c95a4f99a9ca5b1..0f666fc9da83fca7c3b4d1f13d2de05d49e02b2c 100644 (file)
@@ -2530,6 +2530,8 @@ public:
   public:
     SystemObject(RGWRados *_store, RGWObjectCtx& _ctx, rgw_raw_obj& _obj) : store(_store), ctx(_ctx), obj(_obj), state(NULL) {}
 
+    void invalidate_state();
+
     RGWRados *get_store() { return store; }
     rgw_raw_obj& get_obj() { return obj; }
     RGWObjectCtx& get_ctx() { return ctx; }
index 19a0b51db8dbdf7aba33db767d723c57fc39e0bd..6a607f69cb69e7411edf4a2cefc7e7f925617d85 100644 (file)
@@ -47,6 +47,11 @@ int rgw_get_system_obj(RGWRados *rgwstore, RGWObjectCtx& obj_ctx, rgw_pool& pool
   int request_len = READ_CHUNK_LEN;
   rgw_raw_obj obj(pool, key);
 
+  obj_version original_readv;
+  if (objv_tracker && !objv_tracker->read_version.empty()) {
+    original_readv = objv_tracker->read_version;
+  }
+
   do {
     RGWRados::SystemObject source(rgwstore, obj_ctx, obj);
     RGWRados::SystemObject::Read rop(&source);
@@ -64,6 +69,14 @@ int rgw_get_system_obj(RGWRados *rgwstore, RGWObjectCtx& obj_ctx, rgw_pool& pool
     ret = rop.read(0, request_len - 1, bl, objv_tracker);
     if (ret == -ECANCELED) {
       /* raced, restart */
+      if (!original_readv.empty()) {
+        /* we were asked to read a specific obj_version, failed */
+        return ret;
+      }
+      if (objv_tracker) {
+        objv_tracker->read_version.clear();
+      }
+      source.invalidate_state();
       continue;
     }
     if (ret < 0)