void set_fadvise_flags(uint32_t flags) {
data.fadvise_flags = flags;
}
-
void set_fadvise_flag(uint32_t flag) {
data.fadvise_flags = data.fadvise_flags | flag;
}
//append data_bl
data_bl.append(other.data_bl);
}
- void make_op_bl_continue() {
- op_bl.get_contiguous(0, op_bl.length());
- }
/** Inquires about the Transaction as a whole. */
* buffer decoding operation codes and parameters as we go.
*
*/
- class iterator_impl {
- public:
- virtual ~iterator_impl() { }
-
- virtual bool have_op() = 0;
- virtual Op* decode_op() = 0;
- virtual string decode_string() = 0;
- virtual void decode_bl(bufferlist& bl) = 0;
- virtual void decode_attrset(map<string,bufferptr>& aset) = 0;
- virtual void decode_attrset(map<string,bufferlist>& aset) = 0;
- virtual void decode_keyset(set<string> &keys) = 0;
-
- virtual ghobject_t get_oid(__le32 oid_id) = 0;
- virtual coll_t get_cid(__le32 cid_id) = 0;
- virtual uint32_t get_fadvise_flags() const = 0;
-
- friend class Transaction;
- };
-
- class map_iterator : public iterator_impl {
+ class iterator {
Transaction *t;
uint64_t ops;
vector<coll_t> colls;
vector<ghobject_t> objects;
- map_iterator(Transaction *t)
- : t(t), data_bl_p(t->data_bl.begin()) {
+ iterator(Transaction *t)
+ : t(t),
+ data_bl_p(t->data_bl.begin()),
+ colls(t->coll_index.size()),
+ objects(t->object_index.size()) {
ops = t->data.ops;
op_buffer_p = t->op_bl.get_contiguous(0, t->data.ops * sizeof(Op));
- colls.resize(t->coll_index.size());
map<coll_t, __le32>::iterator coll_index_p;
for (coll_index_p = t->coll_index.begin();
coll_index_p != t->coll_index.end();
colls[coll_index_p->second] = coll_index_p->first;
}
- objects.resize(t->object_index.size());
map<ghobject_t, __le32>::iterator object_index_p;
for (object_index_p = t->object_index.begin();
object_index_p != t->object_index.end();
}
};
- class iterator {
- shared_ptr<iterator_impl> impl;
-
- public:
- iterator(Transaction *t) {
- iterator_impl* iterator = NULL;
-
- if (t->use_tbl) {
- assert("tbl encode is not supported" == 0);
- iterator = new map_iterator(t);
- } else {
- iterator = new map_iterator(t);
- }
-
- impl = shared_ptr<iterator_impl>(iterator);
- }
-
- bool have_op() {
- return impl->have_op();
- }
- Op* decode_op() {
- return impl->decode_op();
- }
- void decode_bl(bufferlist& bl) {
- impl->decode_bl(bl);
- }
- string decode_string() {
- return impl->decode_string();
- }
- void decode_attrset(map<string,bufferptr>& aset) {
- impl->decode_attrset(aset);
- }
- void decode_attrset(map<string,bufferlist>& aset) {
- impl->decode_attrset(aset);
- }
- void decode_keyset(set<string> &keys) {
- impl->decode_keyset(keys);
- }
-
- ghobject_t get_oid(__le32 oid_id) {
- return impl->get_oid(oid_id);
- }
- coll_t get_cid(__le32 cid_id) {
- return impl->get_cid(cid_id);
- }
- uint32_t get_fadvise_flags() const {
- return impl->get_fadvise_flags();
- }
- };
-
iterator begin() {
+ if (use_tbl) {
+ _build_actions_from_tbl();
+ }
return iterator(this);
}
+private:
+ void _build_actions_from_tbl();
+
/**
* Helper functions to encode the various mutation elements of a
* transaction. These are 1:1 with the operation codes (see
return index_id;
}
+public:
/// Commence a global file system sync operation.
void start_sync() {
if (use_tbl) {
// etc.
Transaction() :
osr(NULL),
- use_tbl(false),
+ use_tbl(true),
coll_id(0),
object_id(0) { }
Transaction(bufferlist::iterator &dp) :
osr(NULL),
- use_tbl(false),
+ use_tbl(true),
coll_id(0),
object_id(0) {
decode(dp);
Transaction(bufferlist &nbl) :
osr(NULL),
- use_tbl(false),
+ use_tbl(true),
coll_id(0),
object_id(0) {
bufferlist::iterator dp = nbl.begin();
#include "ObjectStore.h"
#include "common/Formatter.h"
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+
+void ObjectStore::Transaction::_build_actions_from_tbl()
+{
+ //used only for tbl encode
+ assert(use_tbl);
+ //Now we assert each transaction should only be iterated once
+ assert(coll_index.size() == 0);
+ assert(object_index.size() == 0);
+ assert(coll_id == 0);
+ assert(object_id == 0);
+ assert(data_bl.length() == 0);
+ assert(op_bl.length() == 0);
+
+ uint64_t ops = data.ops;
+
+ data.ops = 0;
+ use_tbl = false;
+ bufferlist::iterator p = tbl.begin();
+ __u32 op;
+ while(!p.end()) {
+ ::decode(op, p);
+
+ switch(op) {
+ case Transaction::OP_NOP:
+ {
+ nop();
+ }
+ break;
+
+ case Transaction::OP_TOUCH:
+ {
+ coll_t cid;
+ ghobject_t oid;
+
+ ::decode(cid, p);
+ ::decode(oid, p);
+
+ touch(cid, oid);
+ }
+ break;
+
+ case Transaction::OP_WRITE:
+ {
+ coll_t cid;
+ ghobject_t oid;
+ uint64_t off;
+ uint64_t len;
+ bufferlist bl;
+
+ ::decode(cid, p);
+ ::decode(oid, p);
+ ::decode(off, p);
+ ::decode(len, p);
+ ::decode(bl, p);
+
+ write(cid, oid, off, len, bl);
+ }
+ break;
+
+ case Transaction::OP_ZERO:
+ {
+ coll_t cid;
+ ghobject_t oid;
+ uint64_t off;
+ uint64_t len;
+
+ ::decode(cid, p);
+ ::decode(oid, p);
+ ::decode(off, p);
+ ::decode(len, p);
+
+ zero(cid, oid, off, len);
+ }
+ break;
+
+ case Transaction::OP_TRIMCACHE:
+ {
+ coll_t cid;
+ ghobject_t oid;
+ uint64_t off;
+ uint64_t len;
+
+ ::decode(cid, p);
+ ::decode(oid, p);
+ ::decode(off, p);
+ ::decode(len, p);
+
+ // deprecated, no-op
+ }
+ break;
+
+ case Transaction::OP_TRUNCATE:
+ {
+ coll_t cid;
+ ghobject_t oid;
+ uint64_t off;
+
+ ::decode(cid, p);
+ ::decode(oid, p);
+ ::decode(off, p);
+
+ truncate(cid, oid, off);
+ }
+ break;
+
+ case Transaction::OP_REMOVE:
+ {
+ coll_t cid;
+ ghobject_t oid;
+
+ ::decode(cid, p);
+ ::decode(oid, p);
+
+ remove(cid, oid);
+ }
+ break;
+
+ case Transaction::OP_SETATTR:
+ {
+ coll_t cid;
+ ghobject_t oid;
+ string name;
+ bufferlist bl;
+
+ ::decode(cid, p);
+ ::decode(oid, p);
+ ::decode(name, p);
+ ::decode(bl, p);
+
+ setattr(cid, oid, name, bl);
+ }
+ break;
+
+ case Transaction::OP_SETATTRS:
+ {
+ coll_t cid;
+ ghobject_t oid;
+ map<string, bufferptr> aset;
+
+ ::decode(cid, p);
+ ::decode(oid, p);
+ ::decode(aset, p);
+
+ setattrs(cid, oid, aset);
+ }
+ break;
+
+ case Transaction::OP_RMATTR:
+ {
+ coll_t cid;
+ ghobject_t oid;
+ string name;
+
+ ::decode(cid, p);
+ ::decode(oid, p);
+ ::decode(name, p);
+
+ rmattr(cid, oid, name);
+ }
+ break;
+
+ case Transaction::OP_RMATTRS:
+ {
+ coll_t cid;
+ ghobject_t oid;
+
+ ::decode(cid, p);
+ ::decode(oid, p);
+
+ rmattrs(cid, oid);
+ }
+ break;
+
+ case Transaction::OP_CLONE:
+ {
+ coll_t cid;
+ ghobject_t oid;
+ ghobject_t noid;
+
+ ::decode(cid, p);
+ ::decode(oid, p);
+ ::decode(noid, p);
+
+ clone(cid, oid, noid);
+ }
+ break;
+
+ case Transaction::OP_CLONERANGE:
+ {
+ coll_t cid;
+ ghobject_t oid;
+ ghobject_t noid;
+ uint64_t off;
+ uint64_t len;
+
+ ::decode(cid, p);
+ ::decode(oid, p);
+ ::decode(noid, p);
+ ::decode(off, p);
+ ::decode(len, p);
+
+ clone_range(cid, oid, noid, off, len, off);
+ }
+ break;
+
+ case Transaction::OP_CLONERANGE2:
+ {
+ coll_t cid;
+ ghobject_t oid;
+ ghobject_t noid;
+ uint64_t off;
+ uint64_t len;
+ uint64_t dstoff;
+
+ ::decode(cid, p);
+ ::decode(oid, p);
+ ::decode(noid, p);
+ ::decode(off, p);
+ ::decode(len, p);
+ ::decode(dstoff, p);
+
+ clone_range(cid, oid, noid, off, len, dstoff);
+ }
+ break;
+
+ case Transaction::OP_MKCOLL:
+ {
+ coll_t cid;
+
+ ::decode(cid, p);
+
+ create_collection(cid);
+ }
+ break;
+
+ case Transaction::OP_COLL_HINT:
+ {
+ coll_t cid;
+ uint32_t type;
+ bufferlist hint;
+
+ ::decode(cid, p);
+ ::decode(type, p);
+ ::decode(hint, p);
+
+ collection_hint(cid, type, hint);
+ }
+ break;
+
+ case Transaction::OP_RMCOLL:
+ {
+ coll_t cid;
+
+ ::decode(cid, p);
+
+ remove_collection(cid);
+ }
+ break;
+
+ case Transaction::OP_COLL_ADD:
+ {
+ coll_t ncid;
+ coll_t ocid;
+ ghobject_t oid;
+
+ ::decode(ncid, p);
+ ::decode(ocid, p);
+ ::decode(oid, p);
+
+ // always followed by OP_COLL_REMOVE
+ int op;
+ coll_t ocid2;
+ ghobject_t oid2;
+
+ ::decode(op, p);
+ ::decode(ocid2, p);
+ ::decode(oid2, p);
+ assert(op == Transaction::OP_COLL_REMOVE);
+ assert(ocid2 == ocid);
+ assert(oid2 == oid);
+
+ collection_move(ncid, ocid, oid);
+ }
+ break;
+
+ case Transaction::OP_COLL_MOVE:
+ {
+ // WARNING: this is deprecated and buggy; only here to replay old journals.
+ coll_t ocid;
+ coll_t ncid;
+ ghobject_t oid;
+
+ ::decode(ocid, p);
+ ::decode(ncid, p);
+ ::decode(oid, p);
+
+ assert(0 == "OP_COLL_MOVE not supported");
+ }
+ break;
+
+ case Transaction::OP_COLL_MOVE_RENAME:
+ {
+ coll_t oldcid;
+ ghobject_t oldoid;
+ coll_t newcid;
+ ghobject_t newoid;
+
+ ::decode(oldcid, p);
+ ::decode(oldoid, p);
+ ::decode(newcid, p);
+ ::decode(newoid, p);
+
+ collection_move_rename(oldcid, oldoid, newcid, newoid);
+ }
+ break;
+
+ case Transaction::OP_COLL_SETATTR:
+ {
+ coll_t cid;
+ string name;
+ bufferlist bl;
+
+ ::decode(cid, p);
+ ::decode(name, p);
+ ::decode(bl, p);
+
+ collection_setattr(cid, name, bl);
+ }
+ break;
+
+ case Transaction::OP_COLL_SETATTRS:
+ {
+ coll_t cid;
+ map<string,bufferptr> aset;
+
+ ::decode(cid, p);
+ ::decode(aset, p);
+
+ collection_setattrs(cid, aset);
+ }
+ break;
+
+ case Transaction::OP_COLL_RMATTR:
+ {
+ coll_t cid;
+ string name;
+
+ ::decode(cid, p);
+ ::decode(name, p);
+
+ collection_rmattr(cid, name);
+ }
+ break;
+
+ case Transaction::OP_STARTSYNC:
+ {
+ start_sync();
+ }
+ break;
+
+ case Transaction::OP_COLL_RENAME:
+ {
+ coll_t cid;
+ coll_t ncid;
+
+ ::decode(cid, p);
+ ::decode(ncid, p);
+
+ assert(0 == "OP_COLL_REMOVE not supported");
+ }
+ break;
+
+ case Transaction::OP_OMAP_CLEAR:
+ {
+ coll_t cid;
+ ghobject_t oid;
+
+ ::decode(cid, p);
+ ::decode(oid, p);
+
+ omap_clear(cid, oid);
+ }
+ break;
+
+ case Transaction::OP_OMAP_SETKEYS:
+ {
+ coll_t cid;
+ ghobject_t oid;
+ map<string, bufferlist> aset;
+
+ ::decode(cid, p);
+ ::decode(oid, p);
+ ::decode(aset, p);
+
+ omap_setkeys(cid, oid, aset);
+ }
+ break;
+
+ case Transaction::OP_OMAP_RMKEYS:
+ {
+ coll_t cid;
+ ghobject_t oid;
+ set<string> keys;
+
+ ::decode(cid, p);
+ ::decode(oid, p);
+ ::decode(keys, p);
+
+ omap_rmkeys(cid, oid, keys);
+ }
+ break;
+
+ case Transaction::OP_OMAP_RMKEYRANGE:
+ {
+ coll_t cid;
+ ghobject_t oid;
+ string first, last;
+
+ ::decode(cid, p);
+ ::decode(oid, p);
+ ::decode(first, p);
+ ::decode(last, p);
+
+ omap_rmkeyrange(cid, oid, first, last);
+ }
+ break;
+
+ case Transaction::OP_OMAP_SETHEADER:
+ {
+ coll_t cid;
+ ghobject_t oid;
+ bufferlist bl;
+
+ ::decode(cid, p);
+ ::decode(oid, p);
+ ::decode(bl, p);
+
+ omap_setheader(cid, oid, bl);
+ }
+ break;
+
+ case Transaction::OP_SPLIT_COLLECTION:
+ {
+ coll_t cid;
+ uint32_t bits;
+ uint32_t rem;
+ coll_t dest;
+
+ ::decode(cid, p);
+ ::decode(bits, p);
+ ::decode(rem, p);
+ ::decode(dest, p);
+
+ split_collection(cid, bits, rem, dest);
+ }
+ break;
+
+ case Transaction::OP_SPLIT_COLLECTION2:
+ {
+ coll_t cid;
+ uint32_t bits;
+ uint32_t rem;
+ coll_t dest;
+
+ ::decode(cid, p);
+ ::decode(bits, p);
+ ::decode(rem, p);
+ ::decode(dest, p);
+
+ split_collection(cid, bits, rem, dest);
+ }
+ break;
+
+ case Transaction::OP_SETALLOCHINT:
+ {
+ coll_t cid;
+ ghobject_t oid;
+ uint64_t expected_object_size;
+ uint64_t expected_write_size;
+
+ ::decode(cid, p);
+ ::decode(oid, p);
+ ::decode(expected_object_size, p);
+ ::decode(expected_write_size, p);
+
+ set_alloc_hint(cid, oid, expected_object_size, expected_write_size);
+ }
+ break;
+
+ default:
+ assert("Unkown op" == 0);
+ }
+ }
+ use_tbl = true;
+ assert(ops == data.ops);
+}
+
+#pragma GCC diagnostic pop
+
void ObjectStore::Transaction::dump(ceph::Formatter *f)
{
f->open_array_section("ops");