diff options
author | Yehuda Sadeh <yehuda@inktank.com> | 2013-06-19 20:19:39 -0700 |
---|---|---|
committer | Yehuda Sadeh <yehuda@inktank.com> | 2013-06-20 11:04:35 -0700 |
commit | 7b5ec743f03a16bd9a901b754fcb64598e7d6b17 (patch) | |
tree | 622867ce779f4512c57aa6705c0eb7d46041ea19 | |
parent | bfe4bf9d9dc66912c41609cb895ec673d4d03309 (diff) | |
download | ceph-7b5ec743f03a16bd9a901b754fcb64598e7d6b17.tar.gz |
cls_rgw: skip namespaced entries when listing bucket
We added a namespace to the entries, and sadly there can be
valid entries beyond it. Previously we assumed that once we
encounter the namespace tag we're done. That was wrong. We
need to skip the namespace and continue the listing from
there.
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r-- | src/cls/rgw/cls_rgw.cc | 57 |
1 files changed, 55 insertions, 2 deletions
diff --git a/src/cls/rgw/cls_rgw.cc b/src/cls/rgw/cls_rgw.cc index 40394650e28..a75313b95da 100644 --- a/src/cls/rgw/cls_rgw.cc +++ b/src/cls/rgw/cls_rgw.cc @@ -130,6 +130,59 @@ static int log_index_operation(cls_method_context_t hctx, string& obj, RGWModify return cls_cxx_map_set_val(hctx, key, &bl); } +/* + * read list of objects, skips objects in the ugly namespace + */ +static int get_obj_vals(cls_method_context_t hctx, const string& start, const string& filter_prefix, + int num_entries, map<string, bufferlist> *pkeys) +{ + int ret = cls_cxx_map_get_vals(hctx, start, filter_prefix, num_entries, pkeys); + if (ret < 0) + return ret; + + if (pkeys->empty()) + return 0; + + map<string, bufferlist>::reverse_iterator last_element = pkeys->rbegin(); + if ((unsigned char)last_element->first[0] < BI_PREFIX_CHAR) { + /* nothing to see here, move along */ + return 0; + } + + map<string, bufferlist>::iterator first_element = pkeys->begin(); + if ((unsigned char)first_element->first[0] > BI_PREFIX_CHAR) { + return 0; + } + + /* let's rebuild the list, only keep entries we're interested in */ + map<string, bufferlist> old_keys; + old_keys.swap(*pkeys); + + for (map<string, bufferlist>::iterator iter = old_keys.begin(); iter != old_keys.end(); ++iter) { + if ((unsigned char)iter->first[0] != BI_PREFIX_CHAR) { + (*pkeys)[iter->first] = iter->second; + } + } + + if (num_entries == (int)pkeys->size()) + return 0; + + map<string, bufferlist> new_keys; + char c[] = { BI_PREFIX_CHAR + 1, 0 }; + string new_start = c; + + /* now get some more keys */ + ret = cls_cxx_map_get_vals(hctx, new_start, filter_prefix, num_entries - pkeys->size(), &new_keys); + if (ret < 0) + return ret; + + for (map<string, bufferlist>::iterator iter = new_keys.begin(); iter != new_keys.end(); ++iter) { + (*pkeys)[iter->first] = iter->second; + } + + return 0; +} + int rgw_bucket_list(cls_method_context_t hctx, bufferlist *in, bufferlist *out) { bufferlist::iterator iter = in->begin(); @@ -159,7 +212,7 @@ int rgw_bucket_list(cls_method_context_t hctx, bufferlist *in, bufferlist *out) bufferlist bl; map<string, bufferlist> keys; - rc = cls_cxx_map_get_vals(hctx, op.start_obj, op.filter_prefix, op.num_entries + 1, &keys); + rc = get_obj_vals(hctx, op.start_obj, op.filter_prefix, op.num_entries + 1, &keys); if (rc < 0) return rc; @@ -222,7 +275,7 @@ static int check_index(cls_method_context_t hctx, struct rgw_bucket_dir_header * bool done = false; do { - rc = cls_cxx_map_get_vals(hctx, start_obj, filter_prefix, CHECK_CHUNK_SIZE, &keys); + rc = get_obj_vals(hctx, start_obj, filter_prefix, CHECK_CHUNK_SIZE, &keys); if (rc < 0) return rc; |