]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: fix versioned object IO error 10820/head
authorYang Honggang <joseph.yang@xtaotech.com>
Tue, 4 Oct 2016 01:18:09 +0000 (09:18 +0800)
committerYang Honggang <joseph.yang@xtaotech.com>
Tue, 4 Oct 2016 01:18:09 +0000 (09:18 +0800)
    When accessing a copied destination object, its source object's instance ID
    information is needed, however it's missing now in the destination object's
    manifest.

    In order to fix this problem, we can record source object's version_id/instance
    into dest object's manifest(a new filed 'tail_instance' is added). When creating
    a new object(not copy), 'tail_instance' should be equal to its instance value.
    When copy/get a object, 'tail_instance' should always be used to get the right
    tail objects.

Fixes: http://tracker.ceph.com/issues/17111
Signed-off-by: Yang Honggang <joseph.yang@xtaotech.com>
src/rgw/rgw_dencoder.cc
src/rgw/rgw_json_enc.cc
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h

index 0b4fdf5944cf5079fc76b38046b3648b5c47176f..74563963d923a752ab234301aafdf758bbfe7777 100644 (file)
@@ -188,6 +188,10 @@ void RGWObjManifest::get_implicit_location(uint64_t cur_part_id, uint64_t cur_st
   }
 
   location->init_ns(*bucket, oid, ns);
+  
+  // Always overwrite instance with tail_instance
+  // to get the right shadow object location
+  location->set_instance(tail_instance);
 }
 
 
index b519e6a1c678fda3bb4e1bab65c654c6743ab7d2..20a47b6006af55bf7856c7cf77b992e7492ed139 100644 (file)
@@ -87,6 +87,7 @@ void RGWObjManifest::dump(Formatter *f) const
   ::encode_json("prefix", prefix, f);
   ::encode_json("tail_bucket", tail_bucket, f);
   ::encode_json("rules", rules, f);
+  ::encode_json("tail_instance", tail_instance, f);
 }
 
 void rgw_log_entry::dump(Formatter *f) const
index 7d6dc05010e9bc79ad4e1da8ecad91908640958e..1e67f1722662220178bd73696f5e4bf6c4b6f942 100644 (file)
@@ -1948,6 +1948,9 @@ int RGWObjManifest::generator::create_begin(CephContext *cct, RGWObjManifest *_m
 
   manifest->get_implicit_location(cur_part_id, cur_stripe, 0, NULL, &cur_obj);
 
+  // Normal object which not generated through copy operation 
+  manifest->set_tail_instance(_h.get_instance());
+
   manifest->update_iterators();
 
   return 0;
@@ -7018,7 +7021,8 @@ int RGWRados::copy_obj(RGWObjectCtx& obj_ctx,
 
   RGWObjManifest manifest;
   RGWObjState *astate = NULL;
-  ret = get_obj_state(&obj_ctx, src_obj, &astate, NULL);
+
+  ret = get_obj_state(&obj_ctx, src_obj, &astate);
   if (ret < 0) {
     return ret;
   }
index 850fb79e2875ab095af82041280e9981b8983121..00da971f46a9a5a498f2208262689adf6589bc62 100644 (file)
@@ -254,6 +254,8 @@ protected:
                              as object might have been copied across buckets */
   map<uint64_t, RGWObjManifestRule> rules;
 
+  string tail_instance; /* tail object's instance */
+
   void convert_to_explicit();
   int append_explicit(RGWObjManifest& m);
   void append_rules(RGWObjManifest& m, map<uint64_t, RGWObjManifestRule>::iterator& iter, string *override_prefix);
@@ -279,6 +281,7 @@ public:
     prefix = rhs.prefix;
     tail_bucket = rhs.tail_bucket;
     rules = rhs.rules;
+    tail_instance = rhs.tail_instance;
 
     begin_iter.set_manifest(this);
     end_iter.set_manifest(this);
@@ -316,7 +319,7 @@ public:
   }
 
   void encode(bufferlist& bl) const {
-    ENCODE_START(4, 3, bl);
+    ENCODE_START(5, 3, bl);
     ::encode(obj_size, bl);
     ::encode(objs, bl);
     ::encode(explicit_objs, bl);
@@ -326,11 +329,12 @@ public:
     ::encode(prefix, bl);
     ::encode(rules, bl);
     ::encode(tail_bucket, bl);
+    ::encode(tail_instance, bl);
     ENCODE_FINISH(bl);
   }
 
   void decode(bufferlist::iterator& bl) {
-    DECODE_START_LEGACY_COMPAT_LEN_32(4, 2, 2, bl);
+    DECODE_START_LEGACY_COMPAT_LEN_32(5, 2, 2, bl);
     ::decode(obj_size, bl);
     ::decode(objs, bl);
     if (struct_v >= 3) {
@@ -354,6 +358,12 @@ public:
       ::decode(tail_bucket, bl);
     }
 
+    if (struct_v >= 5) {
+      ::decode(tail_instance, bl);
+    } else { // old object created before 'tail_instance' field added to manifest
+      tail_instance = head_obj.get_instance();
+    }
+
     update_iterators();
     DECODE_FINISH(bl);
   }
@@ -411,6 +421,14 @@ public:
     return prefix;
   }
 
+  void set_tail_instance(const string& _ti) {
+    tail_instance = _ti;
+  }
+
+  const string& get_tail_instance() {
+    return tail_instance;
+  }
+
   void set_head_size(uint64_t _s) {
     head_size = _s;
   }