From 52cc9ad09a780d3440e4b358fa05a7cbdb07345d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Piotr=20Da=C5=82ek?= Date: Tue, 18 Apr 2017 15:03:11 +0200 Subject: [PATCH] ObjectStore, *Store: extend fiemap interface MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This extends fiemap interface in objectstore and all data stores so it's possible to pass in the map used later by caller, instead of encoding internal map into bufferlist, then parsing it back into the same type of data container, wasting memory and CPU time in the process. Signed-off-by: Piotr Dałek --- src/os/ObjectStore.h | 19 +++++--- src/os/bluestore/BlueStore.cc | 81 +++++++++++++++++++++++++++-------- src/os/bluestore/BlueStore.h | 9 ++++ src/os/filestore/FileStore.cc | 29 +++++++------ src/os/filestore/FileStore.h | 1 + src/os/kstore/KStore.cc | 20 +++++++-- src/os/kstore/KStore.h | 1 + src/os/memstore/MemStore.cc | 14 ++++-- src/os/memstore/MemStore.h | 1 + 9 files changed, 132 insertions(+), 43 deletions(-) diff --git a/src/os/ObjectStore.h b/src/os/ObjectStore.h index e2cc6e9f910..9c760a91c44 100644 --- a/src/os/ObjectStore.h +++ b/src/os/ObjectStore.h @@ -1717,12 +1717,19 @@ public: * @param bl output bufferlist for extent map information. * @returns 0 on success, negative error code on failure. */ - virtual int fiemap(const coll_t& cid, const ghobject_t& oid, - uint64_t offset, size_t len, bufferlist& bl) = 0; - virtual int fiemap(CollectionHandle& c, const ghobject_t& oid, - uint64_t offset, size_t len, bufferlist& bl) { - return fiemap(c->get_cid(), oid, offset, len, bl); - } + virtual int fiemap(const coll_t& cid, const ghobject_t& oid, + uint64_t offset, size_t len, bufferlist& bl) = 0; + virtual int fiemap(const coll_t& cid, const ghobject_t& oid, + uint64_t offset, size_t len, + map& destmap) = 0; + virtual int fiemap(CollectionHandle& c, const ghobject_t& oid, + uint64_t offset, size_t len, bufferlist& bl) { + return fiemap(c->get_cid(), oid, offset, len, bl); + } + virtual int fiemap(CollectionHandle& c, const ghobject_t& oid, + uint64_t offset, size_t len, map& destmap) { + return fiemap(c->get_cid(), oid, offset, len, destmap); + } /** * getattr -- get an xattr of an object diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index 92afe79c9c0..6350326e20d 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -6192,30 +6192,18 @@ int BlueStore::_decompress(bufferlist& source, bufferlist* result) return r; } -int BlueStore::fiemap( - const coll_t& cid, - const ghobject_t& oid, - uint64_t offset, - size_t len, - bufferlist& bl) -{ - CollectionHandle c = _get_collection(cid); - if (!c) - return -ENOENT; - return fiemap(c, oid, offset, len, bl); -} - -int BlueStore::fiemap( +// this stores fiemap into interval_set, other variations +// use it internally +int BlueStore::_fiemap( CollectionHandle &c_, const ghobject_t& oid, uint64_t offset, size_t length, - bufferlist& bl) + interval_set& destset) { Collection *c = static_cast(c_.get()); if (!c->exists) return -ENOENT; - interval_set m; { RWLock::RLocker l(c->lock); @@ -6252,7 +6240,7 @@ int BlueStore::fiemap( x_len = MIN(x_len, ep->length - x_off); dout(30) << __func__ << " lextent 0x" << std::hex << offset << "~" << x_len << std::dec << " blob " << ep->blob << dendl; - m.insert(offset, x_len); + destset.insert(offset, x_len); length -= x_len; offset += x_len; if (x_off + x_len == ep->length) @@ -6271,12 +6259,67 @@ int BlueStore::fiemap( out: c->trim_cache(); - ::encode(m, bl); dout(20) << __func__ << " 0x" << std::hex << offset << "~" << length - << " size = 0x(" << m << ")" << std::dec << dendl; + << " size = 0x(" << destset << ")" << std::dec << dendl; return 0; } +int BlueStore::fiemap( + const coll_t& cid, + const ghobject_t& oid, + uint64_t offset, + size_t len, + bufferlist& bl) +{ + CollectionHandle c = _get_collection(cid); + if (!c) + return -ENOENT; + return fiemap(c, oid, offset, len, bl); +} + +int BlueStore::fiemap( + CollectionHandle &c_, + const ghobject_t& oid, + uint64_t offset, + size_t length, + bufferlist& bl) +{ + interval_set m; + int r = _fiemap(c_, oid, offset, length, m); + if (r >= 0) { + ::encode(m, bl); + } + return r; +} + +int BlueStore::fiemap( + const coll_t& cid, + const ghobject_t& oid, + uint64_t offset, + size_t len, + map& destmap) +{ + CollectionHandle c = _get_collection(cid); + if (!c) + return -ENOENT; + return fiemap(c, oid, offset, len, destmap); +} + +int BlueStore::fiemap( + CollectionHandle &c_, + const ghobject_t& oid, + uint64_t offset, + size_t length, + map& destmap) +{ + interval_set m; + int r = _fiemap(c_, oid, offset, length, m); + if (r >= 0) { + m.move_into(destmap); + } + return r; +} + int BlueStore::getattr( const coll_t& cid, const ghobject_t& oid, diff --git a/src/os/bluestore/BlueStore.h b/src/os/bluestore/BlueStore.h index 0f79784f061..6220de8a157 100644 --- a/src/os/bluestore/BlueStore.h +++ b/src/os/bluestore/BlueStore.h @@ -2100,10 +2100,19 @@ public: bufferlist& bl, uint32_t op_flags = 0); +private: + int _fiemap(CollectionHandle &c_, const ghobject_t& oid, + uint64_t offset, size_t len, interval_set& destset); +public: int fiemap(const coll_t& cid, const ghobject_t& oid, uint64_t offset, size_t len, bufferlist& bl) override; int fiemap(CollectionHandle &c, const ghobject_t& oid, uint64_t offset, size_t len, bufferlist& bl) override; + int fiemap(const coll_t& cid, const ghobject_t& oid, + uint64_t offset, size_t len, map& destmap) override; + int fiemap(CollectionHandle &c, const ghobject_t& oid, + uint64_t offset, size_t len, map& destmap) override; + int getattr(const coll_t& cid, const ghobject_t& oid, const char *name, bufferptr& value) override; diff --git a/src/os/filestore/FileStore.cc b/src/os/filestore/FileStore.cc index 3b0eabd12d5..2322732ec67 100644 --- a/src/os/filestore/FileStore.cc +++ b/src/os/filestore/FileStore.cc @@ -3325,21 +3325,31 @@ int FileStore::_do_seek_hole_data(int fd, uint64_t offset, size_t len, int FileStore::fiemap(const coll_t& _cid, const ghobject_t& oid, uint64_t offset, size_t len, bufferlist& bl) +{ + map exomap; + int r = fiemap(_cid, oid, offset, len, exomap); + if (r >= 0) { + ::encode(exomap, bl); + } + return r; +} + +int FileStore::fiemap(const coll_t& _cid, const ghobject_t& oid, + uint64_t offset, size_t len, + map& destmap) { tracepoint(objectstore, fiemap_enter, _cid.c_str(), offset, len); const coll_t& cid = !_need_temp_object_collection(_cid, oid) ? _cid : _cid.get_temp(); + destmap.clear(); if ((!backend->has_seek_data_hole() && !backend->has_fiemap()) || len <= (size_t)m_filestore_fiemap_threshold) { - map m; - m[offset] = len; - ::encode(m, bl); + destmap[offset] = len; return 0; } dout(15) << "fiemap " << cid << "/" << oid << " " << offset << "~" << len << dendl; - map exomap; FDRef fd; int r = lfn_open(cid, oid, false, &fd); @@ -3350,27 +3360,22 @@ int FileStore::fiemap(const coll_t& _cid, const ghobject_t& oid, if (backend->has_seek_data_hole()) { dout(15) << "seek_data/seek_hole " << cid << "/" << oid << " " << offset << "~" << len << dendl; - r = _do_seek_hole_data(**fd, offset, len, &exomap); + r = _do_seek_hole_data(**fd, offset, len, &destmap); } else if (backend->has_fiemap()) { dout(15) << "fiemap ioctl" << cid << "/" << oid << " " << offset << "~" << len << dendl; - r = _do_fiemap(**fd, offset, len, &exomap); + r = _do_fiemap(**fd, offset, len, &destmap); } lfn_close(fd); - if (r >= 0) { - ::encode(exomap, bl); - } - done: - dout(10) << "fiemap " << cid << "/" << oid << " " << offset << "~" << len << " = " << r << " num_extents=" << exomap.size() << " " << exomap << dendl; + dout(10) << "fiemap " << cid << "/" << oid << " " << offset << "~" << len << " = " << r << " num_extents=" << destmap.size() << " " << destmap << dendl; assert(!m_filestore_fail_eio || r != -EIO); tracepoint(objectstore, fiemap_exit, r); return r; } - int FileStore::_remove(const coll_t& cid, const ghobject_t& oid, const SequencerPosition &spos) { diff --git a/src/os/filestore/FileStore.h b/src/os/filestore/FileStore.h index a9e51bb6e76..bbae4bc3349 100644 --- a/src/os/filestore/FileStore.h +++ b/src/os/filestore/FileStore.h @@ -583,6 +583,7 @@ public: map *m); using ObjectStore::fiemap; int fiemap(const coll_t& cid, const ghobject_t& oid, uint64_t offset, size_t len, bufferlist& bl) override; + int fiemap(const coll_t& cid, const ghobject_t& oid, uint64_t offset, size_t len, map& destmap) override; int _touch(const coll_t& cid, const ghobject_t& oid); int _write(const coll_t& cid, const ghobject_t& oid, uint64_t offset, size_t len, diff --git a/src/os/kstore/KStore.cc b/src/os/kstore/KStore.cc index 0a543bc72d1..b06b06865d4 100755 --- a/src/os/kstore/KStore.cc +++ b/src/os/kstore/KStore.cc @@ -1280,6 +1280,21 @@ int KStore::fiemap( bufferlist& bl) { map m; + int r = fiemap(cid, oid, offset, len, m); + if (r >= 0) { + ::encode(m, bl); + } + + return r; +} + +int KStore::fiemap( + const coll_t& cid, + const ghobject_t& oid, + uint64_t offset, + size_t len, + map& destmap) +{ CollectionRef c = _get_collection(cid); if (!c) return -ENOENT; @@ -1301,12 +1316,11 @@ int KStore::fiemap( << o->onode.size << dendl; // FIXME: do something smarter here - m[0] = o->onode.size; + destmap[0] = o->onode.size; out: - ::encode(m, bl); dout(20) << __func__ << " " << offset << "~" << len - << " size = 0 (" << m << ")" << dendl; + << " size = 0 (" << destmap << ")" << dendl; return 0; } diff --git a/src/os/kstore/KStore.h b/src/os/kstore/KStore.h index 9df25f4fb4f..bfa1197339f 100644 --- a/src/os/kstore/KStore.h +++ b/src/os/kstore/KStore.h @@ -472,6 +472,7 @@ public: using ObjectStore::fiemap; int fiemap(const coll_t& cid, const ghobject_t& oid, uint64_t offset, size_t len, bufferlist& bl) override; + int fiemap(const coll_t& cid, const ghobject_t& oid, uint64_t offset, size_t len, map& destmap) override; using ObjectStore::getattr; int getattr(const coll_t& cid, const ghobject_t& oid, const char *name, bufferptr& value) override; using ObjectStore::getattrs; diff --git a/src/os/memstore/MemStore.cc b/src/os/memstore/MemStore.cc index c4cc023462e..4b1ca248a43 100644 --- a/src/os/memstore/MemStore.cc +++ b/src/os/memstore/MemStore.cc @@ -355,6 +355,16 @@ int MemStore::read( int MemStore::fiemap(const coll_t& cid, const ghobject_t& oid, uint64_t offset, size_t len, bufferlist& bl) +{ + map destmap; + int r = fiemap(cid, oid, offset, len, destmap); + if (r >= 0) + ::encode(destmap, bl); + return r; +} + +int MemStore::fiemap(const coll_t& cid, const ghobject_t& oid, + uint64_t offset, size_t len, map& destmap) { dout(10) << __func__ << " " << cid << " " << oid << " " << offset << "~" << len << dendl; @@ -365,15 +375,13 @@ int MemStore::fiemap(const coll_t& cid, const ghobject_t& oid, ObjectRef o = c->get_object(oid); if (!o) return -ENOENT; - map m; size_t l = len; if (offset + l > o->get_size()) l = o->get_size() - offset; if (offset >= o->get_size()) goto out; - m[offset] = l; + destmap[offset] = l; out: - ::encode(m, bl); return 0; } diff --git a/src/os/memstore/MemStore.h b/src/os/memstore/MemStore.h index 2cac56fe206..8bf5cc76a5e 100644 --- a/src/os/memstore/MemStore.h +++ b/src/os/memstore/MemStore.h @@ -310,6 +310,7 @@ public: bool allow_eio = false) override; using ObjectStore::fiemap; int fiemap(const coll_t& cid, const ghobject_t& oid, uint64_t offset, size_t len, bufferlist& bl) override; + int fiemap(const coll_t& cid, const ghobject_t& oid, uint64_t offset, size_t len, map& destmap) override; int getattr(const coll_t& cid, const ghobject_t& oid, const char *name, bufferptr& value) override; int getattr(CollectionHandle &c, const ghobject_t& oid, const char *name, -- 2.39.5