#define CEPH_FEATURE_OSD_POOLRESEND (1ULL<<43)
#define CEPH_FEATURE_ERASURE_CODE_PLUGINS_V2 (1ULL<<44)
#define CEPH_FEATURE_OSD_SET_ALLOC_HINT (1ULL<<45)
+#define CEPH_FEATURE_OSD_FADVISE_FLAGS (1ULL<<46)
/*
* The introduction of CEPH_FEATURE_OSD_SNAPMAPPER caused the feature
CEPH_FEATURE_OSD_POOLRESEND | \
CEPH_FEATURE_ERASURE_CODE_PLUGINS_V2 | \
CEPH_FEATURE_OSD_SET_ALLOC_HINT | \
+ CEPH_FEATURE_OSD_FADVISE_FLAGS | \
0ULL)
#define CEPH_FEATURES_SUPPORTED_DEFAULT CEPH_FEATURES_ALL
#include "osd/ECMsgTypes.h"
class MOSDECSubOpRead : public Message {
- static const int HEAD_VERSION = 1;
+ static const int HEAD_VERSION = 2;
static const int COMPAT_VERSION = 1;
public:
virtual void encode_payload(uint64_t features) {
::encode(pgid, payload);
::encode(map_epoch, payload);
- ::encode(op, payload);
+ ::encode(op, payload, features);
}
const char *get_type_name() const { return "MOSDECSubOpRead"; }
const hobject_t &hoid, uint64_t off, uint64_t len,
const set<pg_shard_t> &need,
bool attrs) {
- list<pair<uint64_t, uint64_t> > to_read;
- to_read.push_back(make_pair(off, len));
+ list<boost::tuple<uint64_t, uint64_t, uint32_t> > to_read;
+ to_read.push_back(boost::make_tuple(off, len, 0));
assert(!reads.count(hoid));
reads.insert(
make_pair(
ECSubRead &op,
ECSubReadReply *reply)
{
- for(map<hobject_t, list<pair<uint64_t, uint64_t> > >::iterator i =
+ for(map<hobject_t, list<boost::tuple<uint64_t, uint64_t, uint32_t> > >::iterator i =
op.to_read.begin();
i != op.to_read.end();
++i) {
- for (list<pair<uint64_t, uint64_t> >::iterator j = i->second.begin();
+ for (list<boost::tuple<uint64_t, uint64_t, uint32_t> >::iterator j = i->second.begin();
j != i->second.end();
++j) {
bufferlist bl;
i->first.is_temp() ? temp_coll : coll,
ghobject_t(
i->first, ghobject_t::NO_GEN, get_parent()->whoami_shard().shard),
- j->first,
- j->second,
- bl,
+ j->get<0>(),
+ j->get<1>(),
+ bl, j->get<2>(),
false);
if (r < 0) {
assert(0);
} else {
reply->buffers_read[i->first].push_back(
make_pair(
- j->first,
+ j->get<0>(),
bl)
);
}
// We canceled this read! @see filter_read_op
continue;
}
- list<pair<uint64_t, uint64_t> >::const_iterator req_iter =
+ list<boost::tuple<uint64_t, uint64_t, uint32_t> >::const_iterator req_iter =
rop.to_read.find(i->first)->second.to_read.begin();
list<
boost::tuple<
assert(riter != rop.complete[i->first].returned.end());
pair<uint64_t, uint64_t> adjusted =
sinfo.aligned_offset_len_to_chunk(
- *req_iter);
+ make_pair(req_iter->get<0>(), req_iter->get<1>()));
assert(adjusted.first == j->first);
riter->get<2>()[from].claim(j->second);
}
op.obj_to_source[i->first].insert(*j);
op.source_to_obj[*j].insert(i->first);
}
- for (list<pair<uint64_t, uint64_t> >::const_iterator j =
+ for (list<boost::tuple<uint64_t, uint64_t, uint32_t> >::const_iterator j =
i->second.to_read.begin();
j != i->second.to_read.end();
++j) {
reslist.push_back(
boost::make_tuple(
- j->first,
- j->second,
+ j->get<0>(),
+ j->get<1>(),
map<pg_shard_t, bufferlist>()));
pair<uint64_t, uint64_t> chunk_off_len =
- sinfo.aligned_offset_len_to_chunk(
- *j);
+ sinfo.aligned_offset_len_to_chunk(make_pair(j->get<0>(), j->get<1>()));
for (set<pg_shard_t>::const_iterator k = i->second.need.begin();
k != i->second.need.end();
++k) {
- messages[*k].to_read[i->first].push_back(chunk_off_len);
+ messages[*k].to_read[i->first].push_back(boost::make_tuple(chunk_off_len.first,
+ chunk_off_len.second,
+ j->get<2>()));
}
assert(!need_attrs);
}
public GenContext<pair<RecoveryMessages*, ECBackend::read_result_t& > &> {
ECBackend *ec;
ECBackend::ClientAsyncReadStatus *status;
- list<pair<pair<uint64_t, uint64_t>,
+ list<pair<boost::tuple<uint64_t, uint64_t, uint32_t>,
pair<bufferlist*, Context*> > > to_read;
CallClientContexts(
ECBackend *ec,
ECBackend::ClientAsyncReadStatus *status,
- const list<pair<pair<uint64_t, uint64_t>,
+ const list<pair<boost::tuple<uint64_t, uint64_t, uint32_t>,
pair<bufferlist*, Context*> > > &to_read)
: ec(ec), status(status), to_read(to_read) {}
void finish(pair<RecoveryMessages *, ECBackend::read_result_t &> &in) {
assert(res.returned.size() == to_read.size());
assert(res.r == 0);
assert(res.errors.empty());
- for (list<pair<pair<uint64_t, uint64_t>,
+ for (list<pair<boost::tuple<uint64_t, uint64_t, uint32_t>,
pair<bufferlist*, Context*> > >::iterator i = to_read.begin();
i != to_read.end();
to_read.erase(i++)) {
pair<uint64_t, uint64_t> adjusted =
- ec->sinfo.offset_len_to_stripe_bounds(i->first);
+ ec->sinfo.offset_len_to_stripe_bounds(make_pair(i->first.get<0>(), i->first.get<1>()));
assert(res.returned.front().get<0>() == adjusted.first &&
res.returned.front().get<1>() == adjusted.second);
map<int, bufferlist> to_decode;
assert(i->second.first);
i->second.first->substr_of(
bl,
- i->first.first - adjusted.first,
- MIN(i->first.second, bl.length() - (i->first.first - adjusted.first)));
+ i->first.get<0>() - adjusted.first,
+ MIN(i->first.get<1>(), bl.length() - (i->first.get<0>() - adjusted.first)));
if (i->second.second) {
i->second.second->complete(i->second.first->length());
}
}
}
~CallClientContexts() {
- for (list<pair<pair<uint64_t, uint64_t>,
+ for (list<pair<boost::tuple<uint64_t, uint64_t, uint32_t>,
pair<bufferlist*, Context*> > >::iterator i = to_read.begin();
i != to_read.end();
to_read.erase(i++)) {
void ECBackend::objects_read_async(
const hobject_t &hoid,
- const list<pair<pair<uint64_t, uint64_t>,
+ const list<pair<boost::tuple<uint64_t, uint64_t, uint32_t>,
pair<bufferlist*, Context*> > > &to_read,
Context *on_complete)
{
in_progress_client_reads.push_back(ClientAsyncReadStatus(on_complete));
CallClientContexts *c = new CallClientContexts(
this, &(in_progress_client_reads.back()), to_read);
- list<pair<uint64_t, uint64_t> > offsets;
- for (list<pair<pair<uint64_t, uint64_t>,
+
+ list<boost::tuple<uint64_t, uint64_t, uint32_t> > offsets;
+ pair<uint64_t, uint64_t> tmp;
+ for (list<pair<boost::tuple<uint64_t, uint64_t, uint32_t>,
pair<bufferlist*, Context*> > >::const_iterator i =
to_read.begin();
i != to_read.end();
++i) {
- offsets.push_back(
- sinfo.offset_len_to_stripe_bounds(i->first));
+ tmp = sinfo.offset_len_to_stripe_bounds(make_pair(i->first.get<0>(), i->first.get<1>()));
+ offsets.push_back(boost::make_tuple(tmp.first, tmp.second, i->first.get<2>()));
}
const vector<int> &chunk_mapping = ec_impl->get_chunk_mapping();
list<ClientAsyncReadStatus> in_progress_client_reads;
void objects_read_async(
const hobject_t &hoid,
- const list<pair<pair<uint64_t, uint64_t>,
+ const list<pair<boost::tuple<uint64_t, uint64_t, uint32_t>,
pair<bufferlist*, Context*> > > &to_read,
Context *on_complete);
read_result_t() : r(0) {}
};
struct read_request_t {
- const list<pair<uint64_t, uint64_t> > to_read;
+ const list<boost::tuple<uint64_t, uint64_t, uint32_t> > to_read;
const set<pg_shard_t> need;
const bool want_attrs;
GenContext<pair<RecoveryMessages *, read_result_t& > &> *cb;
read_request_t(
const hobject_t &hoid,
- const list<pair<uint64_t, uint64_t> > &to_read,
+ const list<boost::tuple<uint64_t, uint64_t, uint32_t> > &to_read,
const set<pg_shard_t> &need,
bool want_attrs,
GenContext<pair<RecoveryMessages *, read_result_t& > &> *cb)
o.back()->applied = true;
}
-void ECSubRead::encode(bufferlist &bl) const
+void ECSubRead::encode(bufferlist &bl, uint64_t features) const
{
- ENCODE_START(1, 1, bl);
+ if ((features & CEPH_FEATURE_OSD_FADVISE_FLAGS) == 0) {
+ ENCODE_START(1, 1, bl);
+ ::encode(from, bl);
+ ::encode(tid, bl);
+ map<hobject_t, list<pair<uint64_t, uint64_t> > > tmp;
+ for (map<hobject_t, list<boost::tuple<uint64_t, uint64_t, uint32_t> > >::const_iterator m = to_read.begin();
+ m != to_read.end(); ++m) {
+ list<pair<uint64_t, uint64_t> > tlist;
+ for (list<boost::tuple<uint64_t, uint64_t, uint32_t> >::const_iterator l = m->second.begin();
+ l != m->second.end(); ++l) {
+ tlist.push_back(std::make_pair(l->get<0>(), l->get<1>()));
+ }
+ tmp[m->first] = tlist;
+ }
+ ::encode(tmp, bl);
+ ::encode(attrs_to_read, bl);
+ ENCODE_FINISH(bl);
+ return;
+ }
+
+ ENCODE_START(2, 2, bl);
::encode(from, bl);
::encode(tid, bl);
::encode(to_read, bl);
void ECSubRead::decode(bufferlist::iterator &bl)
{
- DECODE_START(1, bl);
+ DECODE_START(2, bl);
::decode(from, bl);
::decode(tid, bl);
- ::decode(to_read, bl);
+ if (struct_v == 1) {
+ map<hobject_t, list<pair<uint64_t, uint64_t> > >tmp;
+ ::decode(tmp, bl);
+ for (map<hobject_t, list<pair<uint64_t, uint64_t> > >::const_iterator m = tmp.begin();
+ m != tmp.end(); ++m) {
+ list<boost::tuple<uint64_t, uint64_t, uint32_t> > tlist;
+ for (list<pair<uint64_t, uint64_t> > ::const_iterator l = m->second.begin();
+ l != m->second.end(); ++l) {
+ tlist.push_back(boost::make_tuple(l->first, l->second, 0));
+ }
+ to_read[m->first] = tlist;
+ }
+ } else {
+ ::decode(to_read, bl);
+ }
::decode(attrs_to_read, bl);
DECODE_FINISH(bl);
}
f->dump_stream("from") << from;
f->dump_unsigned("tid", tid);
f->open_array_section("objects");
- for (map<hobject_t, list<pair<uint64_t, uint64_t> > >::const_iterator i =
+ for (map<hobject_t, list<boost::tuple<uint64_t, uint64_t, uint32_t> > >::const_iterator i =
to_read.begin();
i != to_read.end();
++i) {
f->open_object_section("object");
f->dump_stream("oid") << i->first;
f->open_array_section("extents");
- for (list<pair<uint64_t, uint64_t> >::const_iterator j =
+ for (list<boost::tuple<uint64_t, uint64_t, uint32_t> >::const_iterator j =
i->second.begin();
j != i->second.end();
++j) {
f->open_object_section("extent");
- f->dump_unsigned("off", j->first);
- f->dump_unsigned("len", j->second);
+ f->dump_unsigned("off", j->get<0>());
+ f->dump_unsigned("len", j->get<1>());
+ f->dump_unsigned("flags", j->get<2>());
f->close_section();
}
f->close_section();
o.push_back(new ECSubRead());
o.back()->from = pg_shard_t(2, shard_id_t(255));
o.back()->tid = 1;
- o.back()->to_read[hoid1].push_back(make_pair(100, 200));
- o.back()->to_read[hoid1].push_back(make_pair(400, 600));
- o.back()->to_read[hoid2].push_back(make_pair(400, 600));
+ o.back()->to_read[hoid1].push_back(boost::make_tuple(100, 200, 0));
+ o.back()->to_read[hoid1].push_back(boost::make_tuple(400, 600, 0));
+ o.back()->to_read[hoid2].push_back(boost::make_tuple(400, 600, 0));
o.back()->attrs_to_read.insert(hoid1);
o.push_back(new ECSubRead());
o.back()->from = pg_shard_t(2, shard_id_t(255));
o.back()->tid = 300;
- o.back()->to_read[hoid1].push_back(make_pair(300, 200));
- o.back()->to_read[hoid2].push_back(make_pair(400, 600));
- o.back()->to_read[hoid2].push_back(make_pair(2000, 600));
+ o.back()->to_read[hoid1].push_back(boost::make_tuple(300, 200, 0));
+ o.back()->to_read[hoid2].push_back(boost::make_tuple(400, 600, 0));
+ o.back()->to_read[hoid2].push_back(boost::make_tuple(2000, 600, 0));
o.back()->attrs_to_read.insert(hoid2);
}
#include "osd_types.h"
#include "include/buffer.h"
#include "os/ObjectStore.h"
+#include "boost/tuple/tuple.hpp"
struct ECSubWrite {
pg_shard_t from;
struct ECSubRead {
pg_shard_t from;
ceph_tid_t tid;
- map<hobject_t, list<pair<uint64_t, uint64_t> > > to_read;
+ map<hobject_t, list<boost::tuple<uint64_t, uint64_t, uint32_t> > > to_read;
set<hobject_t> attrs_to_read;
- void encode(bufferlist &bl) const;
+ void encode(bufferlist &bl, uint64_t features) const;
void decode(bufferlist::iterator &bl);
void dump(Formatter *f) const;
static void generate_test_instances(list<ECSubRead*>& o);
};
-WRITE_CLASS_ENCODER(ECSubRead)
+WRITE_CLASS_ENCODER_FEATURES(ECSubRead)
struct ECSubReadReply {
pg_shard_t from;
virtual void objects_read_async(
const hobject_t &hoid,
- const list<pair<pair<uint64_t, uint64_t>,
+ const list<pair<boost::tuple<uint64_t, uint64_t, uint32_t>,
pair<bufferlist*, Context*> > > &to_read,
Context *on_complete) = 0;
};
void ReplicatedBackend::objects_read_async(
const hobject_t &hoid,
- const list<pair<pair<uint64_t, uint64_t>,
+ const list<pair<boost::tuple<uint64_t, uint64_t, uint32_t>,
pair<bufferlist*, Context*> > > &to_read,
Context *on_complete)
{
int r = 0;
- for (list<pair<pair<uint64_t, uint64_t>,
+ for (list<pair<boost::tuple<uint64_t, uint64_t, uint32_t>,
pair<bufferlist*, Context*> > >::const_iterator i =
to_read.begin();
i != to_read.end() && r >= 0;
++i) {
- int _r = store->read(coll, hoid, i->first.first,
- i->first.second, *(i->second.first));
+ int _r = store->read(coll, hoid, i->first.get<0>(),
+ i->first.get<1>(), *(i->second.first),
+ i->first.get<2>());
if (i->second.second) {
get_parent()->schedule_recovery_work(
get_parent()->bless_gencontext(
void objects_read_async(
const hobject_t &hoid,
- const list<pair<pair<uint64_t, uint64_t>,
+ const list<pair<boost::tuple<uint64_t, uint64_t, uint32_t>,
pair<bufferlist*, Context*> > > &to_read,
Context *on_complete);
} else if (pool.info.require_rollback()) {
ctx->pending_async_reads.push_back(
make_pair(
- make_pair(op.extent.offset, op.extent.length),
+ boost::make_tuple(op.extent.offset, op.extent.length, op.flags),
make_pair(&osd_op.outdata, new FillInExtent(&op.extent.length))));
dout(10) << " async_read noted for " << soid << dendl;
} else {
async_read_started = true;
ctx->pending_async_reads.push_back(
make_pair(
- make_pair(cursor.data_offset, left),
+ boost::make_tuple(cursor.data_offset, left, 0),
make_pair(&bl, cb)));
result = MIN(oi.size - cursor.data_offset, (uint64_t)left);
cb->len = result;
pending_attrs.clear();
}
- // pending async reads <off, len> -> <outbl, outr>
- list<pair<pair<uint64_t, uint64_t>,
+ // pending async reads <off, len, op_flags> -> <outbl, outr>
+ list<pair<boost::tuple<uint64_t, uint64_t, unsigned>,
pair<bufferlist*, Context*> > > pending_async_reads;
int async_read_result;
unsigned inflightreads;
assert(lock_to_release == NONE);
if (reply)
reply->put();
- for (list<pair<pair<uint64_t, uint64_t>,
+ for (list<pair<boost::tuple<uint64_t, uint64_t, unsigned>,
pair<bufferlist*, Context*> > >::iterator i =
pending_async_reads.begin();
i != pending_async_reads.end();
#include "osd/ECMsgTypes.h"
TYPE(ECSubWrite)
TYPE(ECSubWriteReply)
-TYPE(ECSubRead)
+TYPE_FEATUREFUL(ECSubRead)
TYPE(ECSubReadReply)
#include "osd/HitSet.h"