]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: skip prefetch first chunk if range get falls to shadow objects 5258/head
authorYuan Zhou <yuan.zhou@intel.com>
Thu, 16 Jul 2015 08:18:09 +0000 (16:18 +0800)
committerYuan Zhou <yuan.zhou@intel.com>
Fri, 31 Jul 2015 00:42:00 +0000 (08:42 +0800)
Currently the head object will be prefetched in each GET:
 a) This is unnecessary if the Range GET falls to shadow objects.
 b) The GET request would be quite slow if we have a big head object
This patch adds some check on the Range. If it's not in the head
object(>=rgw_max_chunk_size) then skip the prefetch.

Fixes: #12539
Signed-off-by: Yuan Zhou <yuan.zhou@intel.com>
src/rgw/rgw_op.cc
src/rgw/rgw_op.h

index 904b66d12b6aa164d16c5c439c4630748f922391..c3827714d0f1e9e8f10722774b53de420a54f7a2 100644 (file)
@@ -879,6 +879,33 @@ int RGWGetObj::get_data_cb(bufferlist& bl, off_t bl_ofs, off_t bl_len)
   return send_response_data(bl, bl_ofs, bl_len);
 }
 
+bool RGWGetObj::prefetch_data()
+{
+  /* HEAD request, stop prefetch*/
+  if (!get_data) {
+    return false;
+  }
+
+  bool prefetch_first_chunk = true;
+  range_str = s->info.env->get("HTTP_RANGE");
+
+  if(range_str) {
+    int r = parse_range(range_str, ofs, end, &partial_content);
+    /* error on parsing the range, stop prefetch and will fail in execte() */
+    if (r < 0) {
+      range_parsed = false;
+      return false;
+    } else {
+      range_parsed = true;
+    }
+    /* range get goes to shadown objects, stop prefetch */
+    if (ofs >= s->cct->_conf->rgw_max_chunk_size) {
+      prefetch_first_chunk = false;
+    }
+  }
+
+  return get_data && prefetch_first_chunk;
+}
 void RGWGetObj::pre_exec()
 {
   rgw_bucket_object_pre_exec(s);
@@ -960,9 +987,12 @@ done_err:
 int RGWGetObj::init_common()
 {
   if (range_str) {
-    int r = parse_range(range_str, ofs, end, &partial_content);
-    if (r < 0)
-      return r;
+    /* range parsed error when prefetch*/
+    if (!range_parsed) {
+      int r = parse_range(range_str, ofs, end, &partial_content);
+      if (r < 0)
+        return r;
+    }
   }
   if (if_mod) {
     if (parse_time(if_mod, &mod_time) < 0)
index 4ec068dc1295e25d47c09eebd95702b5f59ed1c8..764078b94928953d952d6c697f6e0f27efd34cb8 100644 (file)
@@ -134,6 +134,7 @@ protected:
   int ret;
   bool get_data;
   bool partial_content;
+  bool range_parsed;
   rgw_obj obj;
   utime_t gc_invalidate_time;
 
@@ -156,10 +157,11 @@ public:
     unmod_ptr = NULL;
     get_data = false;
     partial_content = false;
+    range_parsed = false;
     ret = 0;
  }
 
-  virtual bool prefetch_data() { return get_data; }
+  bool prefetch_data();
 
   void set_get_data(bool get_data) {
     this->get_data = get_data;