]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
ObjectStore, *Store: extend fiemap interface
authorPiotr Dałek <piotr.dalek@corp.ovh.com>
Tue, 18 Apr 2017 13:03:11 +0000 (15:03 +0200)
committerPiotr Dałek <piotr.dalek@corp.ovh.com>
Thu, 20 Apr 2017 15:19:00 +0000 (17:19 +0200)
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>
src/os/ObjectStore.h
src/os/bluestore/BlueStore.cc
src/os/bluestore/BlueStore.h
src/os/filestore/FileStore.cc
src/os/filestore/FileStore.h
src/os/kstore/KStore.cc
src/os/kstore/KStore.h
src/os/memstore/MemStore.cc
src/os/memstore/MemStore.h

index e2cc6e9f9101dd79880cc8b00175fc6ae9901d3d..9c760a91c4457517a8a45392e714d4a9c1b1d730 100644 (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
index 92afe79c9c0874afd12d29623246408fc9865845..6350326e20d303cfc3cd5c6a33090d73aac4759c 100644 (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,
index 0f79784f061e1758db95156b0d06203dddc1d149..6220de8a157c6c0d5fb37215e244d3d105bf88f4 100644 (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;
index 3b0eabd12d5656cf57b6906a03f2907844e281cb..2322732ec672d60e7caeec519752e20efa5fc044 100644 (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)
 {
index a9e51bb6e76452f76bd9cb435b844b14c15e77cb..bbae4bc33494a7f3ddc380537454966b8175508c 100644 (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,
index 0a543bc72d14faf6c3ff3948dbbb284eecfe30bd..b06b06865d484f7ddb4ea8c5507bd825dd76388d 100755 (executable)
@@ -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;
 }
 
index 9df25f4fb4fa2de296cb01e115edb664cad9ab55..bfa1197339f71893646353724347347ff114e784 100644 (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;
index c4cc023462e82b7a685aeaa33190342da8529af9..4b1ca248a4353dec354eab5310b45f31ee343b73 100644 (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;
 }
 
index 2cac56fe206e1cc2476b01584eb1c66b6e85340f..8bf5cc76a5ef281c73ac0177e8483efa2c06667a 100644 (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,