From 95745550ce4d201870ce12b871e608cc6c891d6e Mon Sep 17 00:00:00 2001 From: Yuan Zhou Date: Thu, 16 Jul 2015 16:18:09 +0800 Subject: [PATCH] rgw: skip prefetch first chunk if range get falls to shadow objects 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 --- src/rgw/rgw_op.cc | 36 +++++++++++++++++++++++++++++++++--- src/rgw/rgw_op.h | 4 +++- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 904b66d12b6aa..c3827714d0f1e 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -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 @@ void RGWGetObj::execute() 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) diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index 4ec068dc1295e..764078b949289 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -134,6 +134,7 @@ class RGWGetObj : public RGWOp { int ret; bool get_data; bool partial_content; + bool range_parsed; rgw_obj obj; utime_t gc_invalidate_time; @@ -156,10 +157,11 @@ class RGWGetObj : public RGWOp { 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;