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 <piotr.dalek@corp.ovh.com>
This commit is contained in:
Piotr Dałek 2017-04-18 15:03:11 +02:00
parent dcd1687562
commit 52cc9ad09a
9 changed files with 132 additions and 43 deletions

View File

@ -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<uint64_t, uint64_t>& 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<uint64_t, uint64_t>& destmap) {
return fiemap(c->get_cid(), oid, offset, len, destmap);
}
/**
* getattr -- get an xattr of an object

View File

@ -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<uint64_t>& destset)
{
Collection *c = static_cast<Collection *>(c_.get());
if (!c->exists)
return -ENOENT;
interval_set<uint64_t> 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<uint64_t> 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<uint64_t, uint64_t>& 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<uint64_t, uint64_t>& destmap)
{
interval_set<uint64_t> 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,

View File

@ -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<uint64_t>& 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<uint64_t, uint64_t>& destmap) override;
int fiemap(CollectionHandle &c, const ghobject_t& oid,
uint64_t offset, size_t len, map<uint64_t, uint64_t>& destmap) override;
int getattr(const coll_t& cid, const ghobject_t& oid, const char *name,
bufferptr& value) override;

View File

@ -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<uint64_t, uint64_t> 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<uint64_t, uint64_t>& 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<uint64_t, uint64_t> m;
m[offset] = len;
::encode(m, bl);
destmap[offset] = len;
return 0;
}
dout(15) << "fiemap " << cid << "/" << oid << " " << offset << "~" << len << dendl;
map<uint64_t, uint64_t> 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)
{

View File

@ -583,6 +583,7 @@ public:
map<uint64_t, uint64_t> *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<uint64_t, uint64_t>& 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,

View File

@ -1280,6 +1280,21 @@ int KStore::fiemap(
bufferlist& bl)
{
map<uint64_t, uint64_t> 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<uint64_t, uint64_t>& 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;
}

View File

@ -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<uint64_t, uint64_t>& destmap) override;
using ObjectStore::getattr;
int getattr(const coll_t& cid, const ghobject_t& oid, const char *name, bufferptr& value) override;
using ObjectStore::getattrs;

View File

@ -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<uint64_t, uint64_t> 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<uint64_t, uint64_t>& 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<uint64_t, uint64_t> 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;
}

View File

@ -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<uint64_t, uint64_t>& 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,