From: Piotr Dałek Date: Tue, 18 Apr 2017 13:03:11 +0000 (+0200) Subject: ObjectStore, *Store: extend fiemap interface X-Git-Tag: v12.0.3~316^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=52cc9ad09a780d3440e4b358fa05a7cbdb07345d;p=ceph.git ObjectStore, *Store: extend fiemap interface 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 --- diff --git a/src/os/ObjectStore.h b/src/os/ObjectStore.h index e2cc6e9f9101d..9c760a91c4457 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 92afe79c9c087..6350326e20d30 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 0f79784f061e1..6220de8a157c6 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 3b0eabd12d565..2322732ec672d 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 a9e51bb6e7645..bbae4bc33494a 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 0a543bc72d14f..b06b06865d484 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 9df25f4fb4fa2..bfa1197339f71 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 c4cc023462e82..4b1ca248a4353 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 2cac56fe206e1..8bf5cc76a5ef2 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,