const rados_object_list_cursor start,
const rados_object_list_cursor finish,
const size_t result_item_count,
+ const char *filter_buf,
+ const size_t filter_buf_len,
rados_object_list_item *result_items,
rados_object_list_cursor *next)
{
std::list<librados::ListObjectImpl> result;
hobject_t next_hash;
+ bufferlist filter_bl;
+ if (filter_buf != nullptr) {
+ filter_bl.append(filter_buf, filter_buf_len);
+ }
+
C_SaferCond cond;
ctx->objecter->enumerate_objects(
ctx->poolid,
*((hobject_t*)start),
*((hobject_t*)finish),
result_item_count,
+ filter_bl,
&result,
&next_hash,
&cond);
int librados::IoCtx::object_list(const ObjectCursor &start,
const ObjectCursor &finish,
const size_t result_item_count,
+ const bufferlist &filter,
std::vector<ObjectItem> *result,
ObjectCursor *next)
{
*((hobject_t*)start.c_cursor),
*((hobject_t*)finish.c_cursor),
result_item_count,
+ filter,
&obj_result,
&next_hash,
&cond);
const hobject_t &start,
const hobject_t &end,
const uint32_t max,
+ const bufferlist &filter_bl,
std::list<librados::ListObjectImpl> *result,
hobject_t *next,
Context *on_finish)
C_EnumerateReply *on_ack = new C_EnumerateReply(
this, next, result, end, pool_id, on_finish);
- // Construct pgls operation
- bufferlist filter; // FIXME pass in?
-
ObjectOperation op;
- op.pg_nls(max, filter, start, 0);
+ op.pg_nls(max, filter_bl, start, 0);
// Issue. See you later in _enumerate_reply
object_locator_t oloc(pool_id, ns);
osd_op.op.pgls.start_epoch = start_epoch;
::encode(cookie, osd_op.indata);
}
- void add_pgls_filter(int op, uint64_t count, bufferlist& filter,
+ void add_pgls_filter(int op, uint64_t count, const bufferlist& filter,
collection_list_handle_t cookie, epoch_t start_epoch) {
OSDOp& osd_op = add_op(op);
osd_op.op.pgls.count = count;
flags |= CEPH_OSD_FLAG_PGOP;
}
- void pg_nls(uint64_t count, bufferlist& filter,
+ void pg_nls(uint64_t count, const bufferlist& filter,
collection_list_handle_t cookie, epoch_t start_epoch) {
if (filter.length() == 0)
add_pgls(CEPH_OSD_OP_PGNLS, count, cookie, start_epoch);
const hobject_t &start,
const hobject_t &end,
const uint32_t max,
+ const bufferlist &filter_bl,
std::list<librados::ListObjectImpl> *result,
hobject_t *next,
Context *on_finish);
memset(results, 0, sizeof(rados_object_list_item) * 12);
int r = rados_object_list(ioctx,
c, rados_object_list_end(ioctx),
- 12, results, &c);
+ 12, NULL, 0, results, &c);
ASSERT_GE(r, 0);
for (int i = 0; i < r; ++i) {
std::string oid(results[i].oid, results[i].oid_length);
memset(results, 0, sizeof(rados_object_list_item) * 12);
int r = rados_object_list(ioctx,
c, shard_end,
- 12, results, &c);
+ 12, NULL, 0, results, &c);
ASSERT_GE(r, 0);
for (int i = 0; i < r; ++i) {
std::string oid(results[i].oid, results[i].oid_length);
while(!ioctx.object_list_is_end(c))
{
std::vector<ObjectItem> result;
- int r = ioctx.object_list(c, end, 12, &result, &c);
+ int r = ioctx.object_list(c, end, 12, {}, &result, &c);
ASSERT_GE(r, 0);
ASSERT_EQ(r, (int)result.size());
for (int i = 0; i < r; ++i) {
while(c < shard_end)
{
std::vector<ObjectItem> result;
- int r = ioctx.object_list(c, shard_end, 12, &result, &c);
+ int r = ioctx.object_list(c, shard_end, 12, {}, &result, &c);
ASSERT_GE(r, 0);
for (const auto & i : result) {
rados_shutdown(cluster);
}
+TEST_F(LibRadosListPP, EnumerateObjectsFilterPP) {
+ char buf[128];
+ memset(buf, 0xcc, sizeof(buf));
+ bufferlist obj_content;
+ obj_content.append(buf, sizeof(buf));
+
+ std::string target_str = "content";
+
+ // Write xattr bare, no ::encod'ing
+ bufferlist target_val;
+ target_val.append(target_str);
+ bufferlist nontarget_val;
+ nontarget_val.append("rhubarb");
+
+ ASSERT_EQ(0, ioctx.write("has_xattr", obj_content, obj_content.length(), 0));
+ ASSERT_EQ(0, ioctx.write("has_wrong_xattr", obj_content, obj_content.length(), 0));
+ ASSERT_EQ(0, ioctx.write("no_xattr", obj_content, obj_content.length(), 0));
+
+ ASSERT_EQ(0, ioctx.setxattr("has_xattr", "theattr", target_val));
+ ASSERT_EQ(0, ioctx.setxattr("has_wrong_xattr", "theattr", nontarget_val));
+
+ bufferlist filter_bl;
+ std::string filter_name = "plain";
+ ::encode(filter_name, filter_bl);
+ ::encode("_theattr", filter_bl);
+ ::encode(target_str, filter_bl);
+
+ ObjectCursor c = ioctx.object_list_begin();
+ ObjectCursor end = ioctx.object_list_end();
+ bool foundit = false;
+ while(!ioctx.object_list_is_end(c))
+ {
+ std::vector<ObjectItem> result;
+ int r = ioctx.object_list(c, end, 12, filter_bl, &result, &c);
+ ASSERT_GE(r, 0);
+ ASSERT_EQ(r, result.size());
+ for (int i = 0; i < r; ++i) {
+ auto oid = result[i].oid;
+ // We should only see the object that matches the filter
+ ASSERT_EQ(oid, "has_xattr");
+ // We should only see it once
+ ASSERT_FALSE(foundit);
+ foundit = true;
+ }
+ }
+ ASSERT_TRUE(foundit);
+}
+
#pragma GCC diagnostic pop
#pragma GCC diagnostic warning "-Wpragmas"