From: Haomai Wang Date: Thu, 20 Feb 2014 03:43:16 +0000 (+0800) Subject: Add get_*_with_header to StripObjectHeader X-Git-Tag: v0.78~130^2~17 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=d7be540488af7771765a99c773de5e83869f131e;p=ceph.git Add get_*_with_header to StripObjectHeader In some situations, we need to ensure header is held and try to read, so read interfaces need to accept header argument to allow. Signed-off-by: Haomai Wang --- diff --git a/src/os/GenericObjectMap.h b/src/os/GenericObjectMap.h index fddbe53bdf3..88e7b87074a 100644 --- a/src/os/GenericObjectMap.h +++ b/src/os/GenericObjectMap.h @@ -365,11 +365,17 @@ private: int adjust(); }; + protected: typedef ceph::shared_ptr GenericObjectMapIterator; GenericObjectMapIterator _get_iterator(Header header, string prefix) { return GenericObjectMapIterator(new GenericObjectMapIteratorImpl(this, header, prefix)); } + // Scan keys in header into out_keys and out_values (if nonnull) + int scan(Header header, const string &prefix, const set &in_keys, + set *out_keys, map *out_values); + + private: /// Removes node corresponding to header void clear_header(Header header, KeyValueDB::Transaction t); @@ -399,10 +405,6 @@ private: // Lookup header node for input Header lookup_parent(Header input); - // Scan keys in header into out_keys and out_values (if nonnull) - int scan(Header header, const string &prefix, const set &in_keys, - set *out_keys, map *out_values); - // Remove header and all related prefixes int _clear(Header header, KeyValueDB::Transaction t); diff --git a/src/os/KeyValueStore.cc b/src/os/KeyValueStore.cc index b77e7fc6fbc..a12606c875a 100644 --- a/src/os/KeyValueStore.cc +++ b/src/os/KeyValueStore.cc @@ -238,7 +238,39 @@ void StripObjectMap::rename_wrap(const coll_t &cid, const ghobject_t &oid, } } +int StripObjectMap::get_values_with_header(const StripObjectHeader &header, + const string &prefix, + const set &keys, + map *out) +{ + return scan(header.header, prefix, keys, 0, out); +} +int StripObjectMap::get_keys_with_header(const StripObjectHeader &header, + const string &prefix, + set *keys) +{ + ObjectMap::ObjectMapIterator iter = _get_iterator(header.header, prefix); + for (; iter->valid(); iter->next()) { + if (iter->status()) + return iter->status(); + keys->insert(iter->key()); + } + return 0; +} + +int StripObjectMap::get_with_header(const StripObjectHeader &header, + const string &prefix, map *out) +{ + ObjectMap::ObjectMapIterator iter = _get_iterator(header.header, prefix); + for (iter->seek_to_first(); iter->valid(); iter->next()) { + if (iter->status()) + return iter->status(); + out->insert(make_pair(iter->key(), iter->value())); + } + + return 0; +} // =========== KeyValueStore::SubmitManager Implementation ============== uint64_t KeyValueStore::SubmitManager::op_submit_start() @@ -328,8 +360,8 @@ int KeyValueStore::BufferTransaction::get_buffer_key( set keys; map out; keys.insert(key); - int r = store->backend->get_values(strip_header->cid, strip_header->oid, - prefix, keys, &out); + int r = store->backend->get_values_with_header(*strip_header, prefix, + keys, &out); if (r < 0) { dout(10) << __func__ << " " << strip_header->cid << "/" << strip_header->oid << " " << " r = " << r << dendl; @@ -1653,7 +1685,7 @@ int KeyValueStore::_generic_read(coll_t cid, const ghobject_t& oid, } } - r = backend->get_values(cid, oid, OBJECT_STRIP_PREFIX, keys, &out); + r = backend->get_values_with_header(header, OBJECT_STRIP_PREFIX, keys, &out); if (r < 0) { dout(10) << __func__ << " " << cid << "/" << oid << " " << offset << "~" << len << " = " << r << dendl; @@ -2138,7 +2170,7 @@ int KeyValueStore::_rmattrs(coll_t cid, const ghobject_t& oid, return r; } - r = backend->get_keys(cid, oid, OBJECT_XATTR, &attrs); + r = backend->get_keys_with_header(*header, OBJECT_XATTR, &attrs); if (r < 0 && r != -ENOENT) { dout(10) << __func__ << " could not get attrs r = " << r << dendl; assert(!m_fail_eio || r != -EIO); @@ -2648,22 +2680,46 @@ int KeyValueStore::collection_version_current(coll_t c, uint32_t *version) // omap int KeyValueStore::omap_get(coll_t c, const ghobject_t &hoid, - bufferlist *header, map *out) + bufferlist *bl, map *out) { dout(15) << __func__ << " " << c << "/" << hoid << dendl; + StripObjectMap::StripObjectHeader header; + int r = _check_coll(c); if (r < 0) { return r; } - r = backend->get(c, hoid, OBJECT_OMAP, out); + r = backend->lookup_strip_header(c, hoid, header); + if (r < 0) { + dout(10) << __func__ << " lookup_strip_header failed: r =" << r << dendl; + return r; + } + + + r = backend->get_with_header(header, OBJECT_OMAP, out); if (r < 0 && r != -ENOENT) { dout(10) << __func__ << " err r =" << r << dendl; return r; } - return omap_get_header(c, hoid, header, false); + set keys; + map got; + + keys.insert(OBJECT_OMAP_HEADER_KEY); + r = backend->get_values_with_header(header, OBJECT_OMAP_HEADER, keys, &got); + if (r < 0 && r != -ENOENT) { + dout(10) << __func__ << " err r =" << r << dendl; + return r; + } + + if (got.size()) { + assert(got.size() == 1); + bl->swap(got.begin()->second); + } + + return 0; } int KeyValueStore::omap_get_header(coll_t c, const ghobject_t &hoid, @@ -2771,7 +2827,7 @@ int KeyValueStore::_omap_clear(coll_t cid, const ghobject_t &hoid, } set keys; - r = backend->get_keys(cid, hoid, OBJECT_OMAP, &keys); + r = backend->get_keys_with_header(*header, OBJECT_OMAP, &keys); if (r < 0 && r != -ENOENT) { dout(10) << __func__ << " could not get omap_keys r = " << r << dendl; assert(!m_fail_eio || r != -EIO); diff --git a/src/os/KeyValueStore.h b/src/os/KeyValueStore.h index c22185ffd24..2327b0e4076 100644 --- a/src/os/KeyValueStore.h +++ b/src/os/KeyValueStore.h @@ -119,7 +119,24 @@ class StripObjectMap: public GenericObjectMap { KeyValueDB::Transaction t, const SequencerPosition &spos, StripObjectHeader *header); - + // Already hold header to avoid lock header seq again + int get_with_header( + const StripObjectHeader &header, + const string &prefix, + map *out + ); + + int get_values_with_header( + const StripObjectHeader &header, + const string &prefix, + const set &keys, + map *out + ); + int get_keys_with_header( + const StripObjectHeader &header, + const string &prefix, + set *keys + ); StripObjectMap(KeyValueDB *db): GenericObjectMap(db) {}