From f87c4b2c2a6ecadaf9f0e0cfef4b6061878a023b Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Sat, 24 Sep 2016 05:49:37 -0700 Subject: [PATCH] cls/rgw: fix bi_list objclass command was filtering entries, even if filter was not specified, and need to set boundary for plain entries. Also, list_instance_entries() was not working correctly, and added list_olh_entries(). Signed-off-by: Yehuda Sadeh --- src/cls/rgw/cls_rgw.cc | 127 +++++++++++++++++++++++++++++++++++------ 1 file changed, 111 insertions(+), 16 deletions(-) diff --git a/src/cls/rgw/cls_rgw.cc b/src/cls/rgw/cls_rgw.cc index 45506972330cf..0ebc80db73893 100644 --- a/src/cls/rgw/cls_rgw.cc +++ b/src/cls/rgw/cls_rgw.cc @@ -2261,6 +2261,11 @@ static int list_plain_entries(cls_method_context_t hctx, const string& name, con { string filter = name; string start_key = marker; + + string first_instance_idx; + encode_obj_versioned_data_key(string(), &first_instance_idx); + string end_key = first_instance_idx; + int count = 0; map keys; do { @@ -2276,6 +2281,11 @@ static int list_plain_entries(cls_method_context_t hctx, const string& name, con map::iterator iter; for (iter = keys.begin(); iter != keys.end(); ++iter) { + if (iter->first >= end_key) { + /* past the end of plain namespace */ + return count; + } + rgw_cls_bi_entry entry; entry.type = PlainIdx; entry.idx = iter->first; @@ -2293,7 +2303,7 @@ static int list_plain_entries(cls_method_context_t hctx, const string& name, con CLS_LOG(20, "%s(): entry.idx=%s e.key.name=%s", __func__, escape_str(entry.idx).c_str(), escape_str(e.key.name).c_str()); - if (e.key.name != name) { + if (!name.empty() && e.key.name != name) { return count; } @@ -2312,13 +2322,20 @@ static int list_instance_entries(cls_method_context_t hctx, const string& name, cls_rgw_obj_key key(name); string first_instance_idx; encode_obj_versioned_data_key(key, &first_instance_idx); - string start_key = first_instance_idx; + string start_key; + + if (!name.empty()) { + start_key = first_instance_idx; + } else { + start_key = BI_PREFIX_CHAR; + start_key.append(bucket_index_prefixes[BI_BUCKET_OBJ_INSTANCE_INDEX]); + } + string filter = start_key; if (bi_entry_gt(marker, start_key)) { start_key = marker; } int count = 0; map keys; - string filter = first_instance_idx; bool started = true; do { if (count >= (int)max) { @@ -2330,13 +2347,13 @@ static int list_instance_entries(cls_method_context_t hctx, const string& name, if (started) { ret = cls_cxx_map_get_val(hctx, start_key, &keys[start_key]); if (ret == -ENOENT) { - ret = cls_cxx_map_get_vals(hctx, start_key, filter, BI_GET_NUM_KEYS, &keys); + ret = cls_cxx_map_get_vals(hctx, start_key, string(), BI_GET_NUM_KEYS, &keys); } started = false; } else { - ret = cls_cxx_map_get_vals(hctx, start_key, filter, BI_GET_NUM_KEYS, &keys); + ret = cls_cxx_map_get_vals(hctx, start_key, string(), BI_GET_NUM_KEYS, &keys); } - CLS_LOG(20, "%s(): start_key=%s keys.size()=%d", __func__, escape_str(start_key).c_str(), (int)keys.size()); + CLS_LOG(20, "%s(): start_key=%s first_instance_idx=%s keys.size()=%d", __func__, escape_str(start_key).c_str(), escape_str(first_instance_idx).c_str(), (int)keys.size()); if (ret < 0) { return ret; } @@ -2348,6 +2365,10 @@ static int list_instance_entries(cls_method_context_t hctx, const string& name, entry.idx = iter->first; entry.data = iter->second; + if (!filter.empty() && entry.idx.compare(0, filter.size(), filter) != 0) { + return count; + } + CLS_LOG(20, "%s(): entry.idx=%s", __func__, escape_str(entry.idx).c_str()); bufferlist::iterator biter = entry.data.begin(); @@ -2360,7 +2381,85 @@ static int list_instance_entries(cls_method_context_t hctx, const string& name, return -EIO; } - if (e.key.name != name) { + if (!name.empty() && e.key.name != name) { + return count; + } + + entries->push_back(entry); + count++; + start_key = entry.idx; + } + } while (!keys.empty()); + + return count; +} + +static int list_olh_entries(cls_method_context_t hctx, const string& name, const string& marker, uint32_t max, + list *entries) +{ + cls_rgw_obj_key key(name); + string first_instance_idx; + encode_olh_data_key(key, &first_instance_idx); + string start_key; + + if (!name.empty()) { + start_key = first_instance_idx; + } else { + start_key = BI_PREFIX_CHAR; + start_key.append(bucket_index_prefixes[BI_BUCKET_OLH_DATA_INDEX]); + } + string filter = start_key; + if (bi_entry_gt(marker, start_key)) { + start_key = marker; + } + int count = 0; + map keys; + bool started = true; + do { + if (count >= (int)max) { + return count; + } + keys.clear(); +#define BI_GET_NUM_KEYS 128 + int ret; + if (started) { + ret = cls_cxx_map_get_val(hctx, start_key, &keys[start_key]); + if (ret == -ENOENT) { + ret = cls_cxx_map_get_vals(hctx, start_key, string(), BI_GET_NUM_KEYS, &keys); + } + started = false; + } else { + ret = cls_cxx_map_get_vals(hctx, start_key, string(), BI_GET_NUM_KEYS, &keys); + } + CLS_LOG(20, "%s(): start_key=%s first_instance_idx=%s keys.size()=%d", __func__, escape_str(start_key).c_str(), escape_str(first_instance_idx).c_str(), (int)keys.size()); + if (ret < 0) { + return ret; + } + + map::iterator iter; + for (iter = keys.begin(); iter != keys.end(); ++iter) { + rgw_cls_bi_entry entry; + entry.type = OLHIdx; + entry.idx = iter->first; + entry.data = iter->second; + + if (!filter.empty() && entry.idx.compare(0, filter.size(), filter) != 0) { + return count; + } + + CLS_LOG(20, "%s(): entry.idx=%s", __func__, escape_str(entry.idx).c_str()); + + bufferlist::iterator biter = entry.data.begin(); + + rgw_bucket_olh_entry e; + try { + ::decode(e, biter); + } catch (buffer::error& err) { + CLS_LOG(0, "ERROR: %s(): failed to decode buffer (size=%d)", __func__, entry.data.length()); + return -EIO; + } + + if (!name.empty() && e.key.name != name) { return count; } @@ -2398,22 +2497,18 @@ static int rgw_bi_list_op(cls_method_context_t hctx, bufferlist *in, bufferlist } int count = ret; + CLS_LOG(20, "found %d plain entries", count); + ret = list_instance_entries(hctx, op.name, op.marker, max - count, &op_ret.entries); if (ret < 0) { CLS_LOG(0, "ERROR: %s(): list_instance_entries retured ret=%d", __func__, ret); return ret; } - cls_rgw_obj_key key(op.name); - rgw_cls_bi_entry entry; - encode_olh_data_key(key, &entry.idx); - ret = cls_cxx_map_get_val(hctx, entry.idx, &entry.data); - if (ret < 0 && ret != -ENOENT) { - CLS_LOG(0, "ERROR: %s(): cls_cxx_map_get_val retured ret=%d", __func__, ret); + ret = list_olh_entries(hctx, op.name, op.marker, max - count, &op_ret.entries); + if (ret < 0) { + CLS_LOG(0, "ERROR: %s(): list_instance_entries retured ret=%d", __func__, ret); return ret; - } else if (ret >= 0) { - entry.type = OLHIdx; - op_ret.entries.push_back(entry); } ::encode(op_ret, *out); -- 2.39.5