]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: connection reset/crashed when download large zero object with compression enable
authorfang.yuxiang <fang.yuxiang@eisoo.com>
Sat, 27 May 2017 08:21:34 +0000 (16:21 +0800)
committerAdam Kupczyk <akucpzyk@redhat.com>
Mon, 26 Jun 2017 08:55:57 +0000 (04:55 -0400)
large zero object has a large compression rate,
even 4M compressed data can decompress several GB data.
Handle so much data in single process lead strange issue.

Fixes: http://tracker.ceph.com/issues/20098
Signed-off-by: fang yuxiang fang.yuxiang@eisoo.com
src/rgw/rgw_compression.cc

index 1ee8d1263cb1145348f4bd08bccb24717d467d95..1a7758182e481084b49ed7010c06e1ab95067910 100644 (file)
@@ -99,17 +99,33 @@ int RGWGetObj_Decompress::handle_data(bufferlist& bl, off_t bl_ofs, off_t bl_len
       break;
     }
     in_bl.copy(ofs_in_bl, first_block->len, tmp);
-    int cr = compressor->decompress(tmp, tmp_out);
-    if (cr < 0) {
-      lderr(cct) << "Compression failed with exit code " << cr << dendl;
-      return cr;
+    int r = compressor->decompress(tmp, tmp_out);
+    if (r < 0) {
+      lderr(cct) << "Compression failed with exit code " << r << dendl;
+      return r;
     }
     if (first_block == last_block && partial_content)
       tmp_out.copy(0, q_len, out_bl);
-    else
-      out_bl.append(tmp_out);
+    else {
+      out_bl.append(tmp_out);    
+      if (cct->_conf->rgw_max_chunk_size && (out_bl.length() >= cct->_conf->rgw_max_chunk_size)) {
+        if (first_data && partial_content && out_bl.length() != 0)
+          bl_ofs =  q_ofs;
+        
+        if (first_data && out_bl.length() != 0)
+          first_data = false;
+        
+        r = next->handle_data(out_bl, bl_ofs, out_bl.length() - bl_ofs);
+        if (r < 0) {
+          lderr(cct) << "handle_data failed with exit code " << r << dendl;
+          return r;       
+        }  
+        bl_ofs = 0;
+        out_bl.clear();
+      }
+    }
     ++first_block;
 }
+ }
 
   if (first_data && partial_content && out_bl.length() != 0)
     bl_ofs =  q_ofs;
@@ -119,7 +135,12 @@ int RGWGetObj_Decompress::handle_data(bufferlist& bl, off_t bl_ofs, off_t bl_len
 
   cur_ofs += bl_len;
 
-  return next->handle_data(out_bl, bl_ofs, out_bl.length() - bl_ofs);
+  if (out_bl.length()) {
+    assert(out_bl.length() >= bl_ofs); 
+    return next->handle_data(out_bl, bl_ofs, out_bl.length() - bl_ofs);
+  } 
+
+  return 0;
 }
 
 int RGWGetObj_Decompress::fixup_range(off_t& ofs, off_t& end)