/* objects */
int rados_objects_list_open(rados_ioctx_t io, rados_list_ctx_t *ctx);
-int rados_objects_list_next(rados_list_ctx_t ctx, const char **entry);
+int rados_objects_list_next(rados_list_ctx_t ctx, const char **entry, const char **key);
void rados_objects_list_close(rados_list_ctx_t ctx);
/* snapshots */
#include <map>
#include <tr1/memory>
#include <vector>
+#include <utility>
#include "buffer.h"
#include "librados.h"
~ObjectIterator();
bool operator==(const ObjectIterator& rhs) const;
bool operator!=(const ObjectIterator& rhs) const;
- const std::string& operator*() const;
+ const std::pair<std::string, std::string>& operator*() const;
+ const std::pair<std::string, std::string>* operator->() const;
ObjectIterator &operator++(); // Preincrement
ObjectIterator operator++(int); // Postincrement
friend class IoCtx;
private:
void get_next();
std::tr1::shared_ptr < ObjListCtx > ctx;
- std::string cur_obj;
+ std::pair<std::string, std::string> cur_obj;
};
class WatchCtx {
return (ctx.get() != rhs.ctx.get());
}
-const std::string& librados::ObjectIterator::operator*() const {
+const pair<std::string, std::string>& librados::ObjectIterator::operator*() const {
return cur_obj;
}
+const pair<std::string, std::string>* librados::ObjectIterator::operator->() const {
+ return &cur_obj;
+}
+
librados::ObjectIterator& librados::ObjectIterator::operator++()
{
get_next();
void librados::ObjectIterator::get_next()
{
- const char *entry;
- int ret = rados_objects_list_next(ctx.get(), &entry);
+ const char *entry, *key;
+ int ret = rados_objects_list_next(ctx.get(), &entry, &key);
if (ret == -ENOENT) {
ctx.reset();
*this = __EndObjectIterator;
throw std::runtime_error(oss.str());
}
- cur_obj = entry;
+ cur_obj = make_pair(entry, key ? key : string());
}
const librados::ObjectIterator librados::ObjectIterator::__EndObjectIterator(NULL);
delete lh;
}
-extern "C" int rados_objects_list_next(rados_list_ctx_t listctx, const char **entry)
+extern "C" int rados_objects_list_next(rados_list_ctx_t listctx, const char **entry, const char **key)
{
librados::ObjListCtx *lh = (librados::ObjListCtx *)listctx;
Objecter::ListContext *h = lh->lc;
return -ENOENT;
}
- *entry = h->list.front().name.c_str();
+ *entry = h->list.front().first.name.c_str();
+
+ if (key) {
+ if (h->list.front().second.size())
+ *key = h->list.front().second.c_str();
+ else
+ *key = NULL;
+ }
return 0;
}
struct PGLSResponse {
collection_list_handle_t handle;
- list<object_t> entries;
+ list<pair<object_t, string> > entries;
void encode(bufferlist& bl) const {
- __u8 v = 0;
- ::encode(v, bl);
+ __u8 v = 1;
+ ::encode(v, bl);
::encode(handle, bl);
::encode(entries, bl);
}
void decode(bufferlist::iterator& bl) {
- __u8 v;
- ::decode(v, bl);
+ __u8 v;
+ ::decode(v, bl);
+ assert(v == 1);
::decode(handle, bl);
::decode(entries, bl);
}
#include <sstream>
+#include <utility>
#include <errno.h>
}
if (sentries.size() < p->op.pgls.count &&
!response.handle.in_missing_set) {
- // it's a readdir cookie
+ // it's a filestore cookie
dout(10) << " handle high/missing " << response.handle << dendl;
osr.flush(); // order wrt preceeding writes
result = osd->store->collection_list_partial(coll, snapid,
// skip snapdir objects
if (iter->snap == CEPH_SNAPDIR)
continue;
+ bufferlist attr_bl;
+ osd->store->getattr(coll, *iter, OI_ATTR, attr_bl);
+ object_info_t oi(attr_bl);
if (snapid != CEPH_NOSNAP) {
// skip items not defined for this snapshot
if (snapid <= snapset.seq)
continue;
} else {
- bufferlist bl;
- osd->store->getattr(coll, *iter, OI_ATTR, bl);
- object_info_t oi(bl);
bool exists = false;
for (vector<snapid_t>::iterator i = oi.snaps.begin(); i != oi.snaps.end(); ++i)
if (*i == snapid) {
keep = pgls_filter(filter, *iter, filter_out);
if (keep)
- response.entries.push_back(iter->oid);
+ response.entries.push_back(make_pair(iter->oid, oi.oloc.key));
}
::encode(response, outdata);
if (filter)
int64_t pool_id;
int pool_snap_seq;
int max_entries;
- std::list<object_t> list;
+ std::list<pair<object_t, string> > list;
bufferlist filter;
ExportLocalFileWQ export_object_wq(io_ctx_dist, time(NULL),
tp, export_dir.get(), force);
for (; oi != oi_end; ++oi) {
- export_object_wq.queue(new std::string(*oi));
+ export_object_wq.queue(new std::string((*oi).first));
}
export_object_wq.drain();
librados::ObjectIterator oi = io_ctx.objects_begin();
librados::ObjectIterator oi_end = io_ctx.objects_end();
for (; oi != oi_end; ++oi) {
- import_val_wq.queue(new std::string(*oi));
+ import_val_wq.queue(new std::string((*oi).first));
}
import_val_wq.drain();
}
return -ENOENT;
}
- obj.name = **state;
+ obj.name = (*state)->first;
(*state)++;
} while (obj.name[0] == '.');
return -ENOENT;
}
if (state->prefix.length() &&
- (*state->obit).find(state->prefix) != 0) {
+ state->obit->first.find(state->prefix) != 0) {
state->obit++;
continue;
}
- *name = *state->obit;
+ *name = state->obit->first;
state->obit++;
break;
}
librados::ObjectIterator iter = io_ctx.objects_begin();
while (iter != io_ctx.objects_end()) {
- const std::string& oid = *iter;
+ const std::string& oid = iter->first;
if (oid.compare(start) >= 0)
break;
for (i = 0; i < num && iter != io_ctx.objects_end(); ++i, ++iter) {
RGWObjEnt e;
- const string &oid = *iter;
+ const string &oid = iter->first;
// fill it in with initial values; we may correct later
e.name = oid;
r = rados_objects_list_open(io_ctx, &h);
printf("rados_list_objects_open = %d, h = %p\n", r, h);
const char *poolname;
- while (rados_objects_list_next(h, &poolname) == 0)
+ while (rados_objects_list_next(h, &poolname, NULL) == 0)
printf("rados_list_objects_next got object '%s'\n", poolname);
rados_objects_list_close(h);
rados_list_ctx_t ctx;
ASSERT_EQ(0, rados_objects_list_open(ioctx, &ctx));
const char *entry;
- ASSERT_EQ(0, rados_objects_list_next(ctx, &entry));
+ ASSERT_EQ(0, rados_objects_list_next(ctx, &entry, NULL));
ASSERT_EQ(std::string(entry), "foo");
- ASSERT_EQ(-ENOENT, rados_objects_list_next(ctx, &entry));
+ ASSERT_EQ(-ENOENT, rados_objects_list_next(ctx, &entry, NULL));
rados_objects_list_close(ctx);
rados_ioctx_destroy(ioctx);
ASSERT_EQ(0, destroy_one_pool(pool_name, &cluster));
ASSERT_EQ((int)sizeof(buf), ioctx.write("foo", bl1, sizeof(buf), 0));
ObjectIterator iter(ioctx.objects_begin());
ASSERT_EQ(false, (iter == ioctx.objects_end()));
- ASSERT_EQ(*iter, "foo");
+ ASSERT_EQ((*iter).first, "foo");
++iter;
ASSERT_EQ(true, (iter == ioctx.objects_end()));
ioctx.close();
printf("%s: listing objects.\n", get_id_str());
RETURN1_IF_NONZERO(rados_objects_list_open(io_ctx, &h));
while (true) {
- ret = rados_objects_list_next(h, &obj_name);
+ ret = rados_objects_list_next(h, &obj_name, NULL);
if (ret == -ENOENT) {
break;
}