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;
if (!o || !o->exists) {
return -ENOENT;
}
+ _dump_onode(o);
if (offset == len && offset == 0)
len = o->onode.size;
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;
// 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;
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
}
}
+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;