From 22f73ba62eb1fe337622ea2aefdcd829f8def851 Mon Sep 17 00:00:00 2001 From: Jianpeng Ma Date: Wed, 19 Sep 2018 20:45:17 +0800 Subject: [PATCH] os/objectstore: add new op OP_CREATE for create a new object. For OP_CREATE in bluestore mean node didn't exist, so skip search form kvdb. Signed-off-by: Jianpeng Ma --- src/os/ObjectStore.h | 15 +++++++++++++++ src/os/Transaction.cc | 10 ++++++++++ src/os/bluestore/BlueStore.cc | 23 ++++++++++++++++------- src/os/bluestore/BlueStore.h | 2 +- src/os/filestore/FileStore.cc | 1 + src/os/kstore/KStore.cc | 2 ++ src/os/memstore/MemStore.cc | 1 + src/osd/ECTransaction.cc | 2 +- src/osd/ReplicatedBackend.cc | 2 +- 9 files changed, 48 insertions(+), 10 deletions(-) diff --git a/src/os/ObjectStore.h b/src/os/ObjectStore.h index 3c2ced9af051..d8978cff5c41 100644 --- a/src/os/ObjectStore.h +++ b/src/os/ObjectStore.h @@ -307,6 +307,7 @@ public: public: enum { OP_NOP = 0, + OP_CREATE = 7, // cid, oid OP_TOUCH = 9, // cid, oid OP_WRITE = 10, // cid, oid, offset, len, bl OP_ZERO = 11, // cid, oid, offset, len @@ -601,6 +602,7 @@ public: case OP_NOP: break; + case OP_CREATE: case OP_TOUCH: case OP_REMOVE: case OP_SETATTR: @@ -996,6 +998,19 @@ public: _op->op = OP_NOP; data.ops++; } + /** + * create + * + * create an object that does not yet exist + * (behavior is undefined if the object already exists) + */ + void create(const coll_t& cid, const ghobject_t& oid) { + Op* _op = _get_next_op(); + _op->op = OP_CREATE; + _op->cid = _get_coll_id(cid); + _op->oid = _get_object_id(oid); + data.ops++; + } /** * touch * diff --git a/src/os/Transaction.cc b/src/os/Transaction.cc index ad390a1c3eee..e0c2b7b26ac3 100644 --- a/src/os/Transaction.cc +++ b/src/os/Transaction.cc @@ -19,6 +19,16 @@ void ObjectStore::Transaction::dump(ceph::Formatter *f) case Transaction::OP_NOP: f->dump_string("op_name", "nop"); break; + case Transaction::OP_CREATE: + { + coll_t cid = i.get_cid(op->cid); + ghobject_t oid = i.get_oid(op->oid); + f->dump_string("op_name", "create"); + f->dump_stream("collection") << cid; + f->dump_stream("oid") << oid; + } + break; + case Transaction::OP_TOUCH: { coll_t cid = i.get_cid(op->cid); diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index e0de190a1dd8..962c40777596 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -3299,7 +3299,8 @@ uint64_t BlueStore::Collection::make_blob_unshared(SharedBlob *sb) BlueStore::OnodeRef BlueStore::Collection::get_onode( const ghobject_t& oid, - bool create) + bool create, + bool is_createop) { ceph_assert(create ? lock.is_wlocked() : lock.is_locked()); @@ -3312,9 +3313,12 @@ BlueStore::OnodeRef BlueStore::Collection::get_onode( } } - OnodeRef o = onode_map.lookup(oid); - if (o) - return o; + OnodeRef o = OnodeRef(); + if (!is_createop) { + o = onode_map.lookup(oid); + if (o) + return o; + } mempool::bluestore_cache_other::string key; get_object_key(store->cct, oid, &key); @@ -3323,9 +3327,12 @@ BlueStore::OnodeRef BlueStore::Collection::get_onode( << pretty_binary_string(key) << dendl; bufferlist v; - int r = store->db->get(PREFIX_OBJ, key.c_str(), key.size(), &v); - ldout(store->cct, 20) << " r " << r << " v.len " << v.length() << dendl; + int r = -ENOENT; Onode *on; + if (!is_createop) { + r = store->db->get(PREFIX_OBJ, key.c_str(), key.size(), &v); + ldout(store->cct, 20) << " r " << r << " v.len " << v.length() << dendl; + } if (v.length() == 0) { ceph_assert(r == -ENOENT); if (!store->cct->_conf->bluestore_debug_misc && @@ -10399,6 +10406,7 @@ void BlueStore::_txc_add_transaction(TransContext *txc, Transaction *t) // these operations implicity create the object bool create = false; if (op->op == Transaction::OP_TOUCH || + op->op == Transaction::OP_CREATE || op->op == Transaction::OP_WRITE || op->op == Transaction::OP_ZERO) { create = true; @@ -10409,7 +10417,7 @@ void BlueStore::_txc_add_transaction(TransContext *txc, Transaction *t) OnodeRef &o = ovec[op->oid]; if (!o) { ghobject_t oid = i.get_oid(op->oid); - o = c->get_onode(oid, create); + o = c->get_onode(oid, create, op->op == Transaction::OP_CREATE); } if (!create && (!o || !o->exists)) { dout(10) << __func__ << " op " << op->op << " got ENOENT on " @@ -10419,6 +10427,7 @@ void BlueStore::_txc_add_transaction(TransContext *txc, Transaction *t) } switch (op->op) { + case Transaction::OP_CREATE: case Transaction::OP_TOUCH: r = _touch(txc, c, o); break; diff --git a/src/os/bluestore/BlueStore.h b/src/os/bluestore/BlueStore.h index 05324916456e..cc80b949f329 100644 --- a/src/os/bluestore/BlueStore.h +++ b/src/os/bluestore/BlueStore.h @@ -1379,7 +1379,7 @@ public: pool_opts_t pool_opts; ContextQueue *commit_queue; - OnodeRef get_onode(const ghobject_t& oid, bool create); + OnodeRef get_onode(const ghobject_t& oid, bool create, bool is_createop=false); // the terminology is confusing here, sorry! // diff --git a/src/os/filestore/FileStore.cc b/src/os/filestore/FileStore.cc index 46a27b058752..970a1db5e2b7 100644 --- a/src/os/filestore/FileStore.cc +++ b/src/os/filestore/FileStore.cc @@ -2749,6 +2749,7 @@ void FileStore::_do_transaction( switch (op->op) { case Transaction::OP_NOP: break; + case Transaction::OP_CREATE: case Transaction::OP_TOUCH: { const coll_t &_cid = i.get_cid(op->cid); diff --git a/src/os/kstore/KStore.cc b/src/os/kstore/KStore.cc index 616ca1b6a25e..5c447145383b 100644 --- a/src/os/kstore/KStore.cc +++ b/src/os/kstore/KStore.cc @@ -2308,6 +2308,7 @@ void KStore::_txc_add_transaction(TransContext *txc, Transaction *t) // these operations implicity create the object bool create = false; if (op->op == Transaction::OP_TOUCH || + op->op == Transaction::OP_CREATE || op->op == Transaction::OP_WRITE || op->op == Transaction::OP_ZERO) { create = true; @@ -2325,6 +2326,7 @@ void KStore::_txc_add_transaction(TransContext *txc, Transaction *t) } switch (op->op) { + case Transaction::OP_CREATE: case Transaction::OP_TOUCH: r = _touch(txc, c, o); break; diff --git a/src/os/memstore/MemStore.cc b/src/os/memstore/MemStore.cc index f3a7e39abbbe..7e1c96e0411c 100644 --- a/src/os/memstore/MemStore.cc +++ b/src/os/memstore/MemStore.cc @@ -662,6 +662,7 @@ void MemStore::_do_transaction(Transaction& t) switch (op->op) { case Transaction::OP_NOP: break; + case Transaction::OP_CREATE: case Transaction::OP_TOUCH: { coll_t cid = i.get_cid(op->cid); diff --git a/src/osd/ECTransaction.cc b/src/osd/ECTransaction.cc index ee791d633c6e..e2db8aa5508d 100644 --- a/src/osd/ECTransaction.cc +++ b/src/osd/ECTransaction.cc @@ -264,7 +264,7 @@ void ECTransaction::generate_transactions( [&](const PGTransaction::ObjectOperation::Init::None &) {}, [&](const PGTransaction::ObjectOperation::Init::Create &op) { for (auto &&st: *transactions) { - st.second.touch( + st.second.create( coll_t(spg_t(pgid, st.first)), ghobject_t(oid, ghobject_t::NO_GEN, st.first)); } diff --git a/src/osd/ReplicatedBackend.cc b/src/osd/ReplicatedBackend.cc index fb93bf9a5878..92a686825715 100644 --- a/src/osd/ReplicatedBackend.cc +++ b/src/osd/ReplicatedBackend.cc @@ -322,7 +322,7 @@ void generate_transaction( [&](const PGTransaction::ObjectOperation::Init::None &) { }, [&](const PGTransaction::ObjectOperation::Init::Create &op) { - t->touch(coll, goid); + t->create(coll, goid); }, [&](const PGTransaction::ObjectOperation::Init::Clone &op) { t->clone( -- 2.47.3