]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: fix fiemap
authorSage Weil <sage@redhat.com>
Wed, 6 Jan 2016 17:54:23 +0000 (12:54 -0500)
committerSage Weil <sage@redhat.com>
Fri, 8 Jan 2016 18:10:19 +0000 (13:10 -0500)
Signed-off-by: Sage Weil <sage@redhat.com>
src/os/bluestore/BlueStore.cc
src/test/objectstore/store_test.cc

index c8e0e1e9711bbb615e7e08597c140098db56e8a6..000651cb15b7781269324845cb84b59b20fa3374 100644 (file)
@@ -2453,7 +2453,7 @@ int BlueStore::fiemap(
   size_t len,
   bufferlist& bl)
 {
-  map<uint64_t, uint64_t> m;
+  interval_set<uint64_t> m;
   CollectionRef c = _get_collection(cid);
   if (!c)
     return -ENOENT;
@@ -2463,6 +2463,7 @@ int BlueStore::fiemap(
   if (!o || !o->exists) {
     return -ENOENT;
   }
+  _dump_onode(o);
 
   if (offset == len && offset == 0)
     len = o->onode.size;
@@ -2491,8 +2492,8 @@ int BlueStore::fiemap(
   if (op != o->onode.overlay_map.begin()) {
     --op;
   }
-  uint64_t start = offset;
   while (len > 0) {
+    dout(20) << __func__ << " offset " << offset << dendl;
     if (op != oend && op->first + op->second.length < offset) {
       ++op;
       continue;
@@ -2505,8 +2506,8 @@ int BlueStore::fiemap(
     // overlay?
     if (op != oend && op->first <= offset) {
       uint64_t x_len = MIN(op->first + op->second.length - offset, len);
-      //m[offset] = x_len;
       dout(30) << __func__ << " overlay " << offset << "~" << x_len << dendl;
+      m.insert(offset, x_len);
       len -= x_len;
       offset += x_len;
       ++op;
@@ -2525,27 +2526,22 @@ int BlueStore::fiemap(
       uint64_t x_off = offset - bp->first;
       x_len = MIN(x_len, bp->second.length - x_off);
       dout(30) << __func__ << " extent " << offset << "~" << x_len << dendl;
+      m.insert(offset, x_len);
       len -= x_len;
       offset += x_len;
       if (x_off + x_len == bp->second.length)
        ++bp;
       continue;
     }
-    if (offset - start) {
-      // we are seeing a hole, time to add an entry to fiemap.
-      m[start] = offset - start;
-      dout(20) << __func__ << " out " << start << "~" << m[start] << dendl;
+    if (bp != bend &&
+       bp->first > offset &&
+       bp->first - offset < x_len) {
+      x_len = bp->first - offset;
     }
     offset += x_len;
-    start = offset;
     len -= x_len;
     continue;
   }
-  // add tailing
-  if (offset - start != 0) {
-    m[start] = offset - start;
-    dout(20) << __func__ << " out " << start << "~" << m[start] << dendl;
-  }
 
   ::encode(m, bl);
   dout(20) << __func__ << " " << offset << "~" << len
index 4cb84934b657dd83964ff791ce1644695cee7e9a..d57e82c221dd52c61314175a183a05ef56abccbf 100644 (file)
@@ -248,6 +248,49 @@ TEST_P(StoreTest, FiemapEmpty) {
   }
 }
 
+TEST_P(StoreTest, FiemapHoles) {
+  ObjectStore::Sequencer osr("test");
+  coll_t cid;
+  int r = 0;
+  ghobject_t oid(hobject_t(sobject_t("fiemap_object", CEPH_NOSNAP)));
+  bufferlist bl;
+  bl.append("foo");
+  {
+    ObjectStore::Transaction t;
+    t.create_collection(cid, 0);
+    t.touch(cid, oid);
+    t.write(cid, oid, 0, 3, bl);
+    t.write(cid, oid, 1048576, 3, bl);
+    t.write(cid, oid, 4194304, 3, bl);
+    r = store->apply_transaction(&osr, t);
+    ASSERT_EQ(r, 0);
+  }
+  {
+    bufferlist bl;
+    store->fiemap(cid, oid, 0, 0, bl);
+    map<uint64_t,uint64_t> m, e;
+    bufferlist::iterator p = bl.begin();
+    ::decode(m, p);
+    cout << " got " << m << std::endl;
+    ASSERT_TRUE(!m.empty());
+    ASSERT_GE(m[0], 3);
+    ASSERT_TRUE((m.size() == 1 &&
+                m[0] > 4194304u) ||
+               (m.size() == 3 &&
+                m.count(0) &&
+                m.count(1048576) &&
+                m.count(4194304)));
+  }
+  {
+    ObjectStore::Transaction t;
+    t.remove(cid, oid);
+    t.remove_collection(cid);
+    cerr << "remove collection" << std::endl;
+    r = store->apply_transaction(&osr, t);
+    ASSERT_EQ(r, 0);
+  }
+}
+
 TEST_P(StoreTest, SimpleMetaColTest) {
   ObjectStore::Sequencer osr("test");
   coll_t cid;