mirror of
https://github.com/ceph/ceph
synced 2025-01-03 01:22:53 +00:00
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:
parent
dcd1687562
commit
52cc9ad09a
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user