From: Sage Weil Date: Wed, 6 Jan 2016 17:54:23 +0000 (-0500) Subject: os/bluestore: fix fiemap X-Git-Tag: v10.0.3~88^2~14 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e29ca1cfd7292d117be4d5234287ff995e0a7032;p=ceph.git os/bluestore: fix fiemap Signed-off-by: Sage Weil --- diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index c8e0e1e9711b..000651cb15b7 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -2453,7 +2453,7 @@ int BlueStore::fiemap( size_t len, bufferlist& bl) { - map m; + interval_set 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 diff --git a/src/test/objectstore/store_test.cc b/src/test/objectstore/store_test.cc index 4cb84934b657..d57e82c221dd 100644 --- a/src/test/objectstore/store_test.cc +++ b/src/test/objectstore/store_test.cc @@ -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 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;