]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: fix extra_data_len handling in PutObj filters 18867/head
authorCasey Bodley <cbodley@redhat.com>
Mon, 23 Oct 2017 18:23:32 +0000 (14:23 -0400)
committerShinobu Kinjo <shinobu@redhat.com>
Fri, 10 Nov 2017 07:07:49 +0000 (02:07 -0500)
the RGWPutObj_Compress filter relies on a starting offset of 0 to ensure
that we only compress entire objects

for RGWRados::fetch_remote_obj(), we also fetch object metadata. the
replies come back with a 'Rgwx-Embedded-Metadata-Len' header, which
specifies how many bytes of object metadata are at the front of the
request body. when this is present, the offsets passed from
RGWRadosPutObj down to the RGWPutObjDataProcessor filters are offsets
into the http response body, rather than logical offsets into the object
data itself

this commit adds a transformation to RGWRadosPutObj so that only that
logical offset is visible to the RGWPutObjDataProcessor

Fixes: http://tracker.ceph.com/issues/21895
Signed-off-by: Casey Bodley <cbodley@redhat.com>
(cherry picked from commit ac7ffe6ef7faef4e251c970ce2efd04616c0459c)

src/rgw/rgw_rados.cc

index a44fc01a850342f51fa5064a7f556f6e7270d125..14068c2d8dd8dd6b53485ed4449d9abe78ccba83 100644 (file)
@@ -7253,7 +7253,7 @@ class RGWRadosPutObj : public RGWGetDataCB
   void (*progress_cb)(off_t, void *);
   void *progress_data;
   bufferlist extra_data_bl;
-  uint64_t extra_data_len;
+  uint64_t extra_data_left;
   uint64_t data_len;
   map<string, bufferlist> src_attrs;
 public:
@@ -7272,7 +7272,7 @@ public:
                        opstate(_ops),
                        progress_cb(_progress_cb),
                        progress_data(_progress_data),
-                       extra_data_len(0),
+                       extra_data_left(0),
                        data_len(0) {}
 
   int process_attrs(void) {
@@ -7301,17 +7301,17 @@ public:
     if (progress_cb) {
       progress_cb(ofs, progress_data);
     }
-    if (extra_data_len) {
+    if (extra_data_left) {
       size_t extra_len = bl.length();
-      if (extra_len > extra_data_len)
-        extra_len = extra_data_len;
+      if (extra_len > extra_data_left)
+        extra_len = extra_data_left;
 
       bufferlist extra;
       bl.splice(0, extra_len, &extra);
       extra_data_bl.append(extra);
 
-      extra_data_len -= extra_len;
-      if (extra_data_len == 0) {
+      extra_data_left -= extra_len;
+      if (extra_data_left == 0) {
         int res = process_attrs();
         if (res < 0)
           return res;
@@ -7319,7 +7319,13 @@ public:
       if (bl.length() == 0) {
         return 0;
       }
+      ofs += extra_len;
     }
+    // adjust ofs based on extra_data_len, so the result is a logical offset
+    // into the object data
+    assert(uint64_t(ofs) >= extra_data_len);
+    ofs -= extra_data_len;
+
     data_len += bl.length();
     bool again = false;
 
@@ -7363,7 +7369,8 @@ public:
   map<string, bufferlist>& get_attrs() { return src_attrs; }
 
   void set_extra_data_len(uint64_t len) override {
-    extra_data_len = len;
+    extra_data_left = len;
+    RGWGetDataCB::set_extra_data_len(len);
   }
 
   uint64_t get_data_len() {