mirror of
https://github.com/ceph/ceph
synced 2025-02-21 01:47:25 +00:00
Merge pull request #11554 from mslovy/wip-fix-fiemap
os/FileStore: fix fiemap issue in xfs when #extents > 1364 Reviewed-by: Sage Weil <sage@redhat.com>
This commit is contained in:
commit
ab0b6dffed
@ -3170,11 +3170,13 @@ int FileStore::read(
|
||||
int FileStore::_do_fiemap(int fd, uint64_t offset, size_t len,
|
||||
map<uint64_t, uint64_t> *m)
|
||||
{
|
||||
struct fiemap *fiemap = NULL;
|
||||
uint64_t i;
|
||||
struct fiemap_extent *extent = NULL;
|
||||
struct fiemap_extent *last = NULL;
|
||||
struct fiemap *fiemap = NULL;
|
||||
int r = 0;
|
||||
|
||||
more:
|
||||
r = backend->do_fiemap(fd, offset, len, &fiemap);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -3214,9 +3216,15 @@ int FileStore::_do_fiemap(int fd, uint64_t offset, size_t len,
|
||||
extent->fe_length = offset + len - extent->fe_logical;
|
||||
(*m)[extent->fe_logical] = extent->fe_length;
|
||||
i++;
|
||||
extent++;
|
||||
last = extent++;
|
||||
}
|
||||
free(fiemap);
|
||||
if (!(last->fe_flags & FIEMAP_EXTENT_LAST)) {
|
||||
uint64_t xoffset = last->fe_logical + last->fe_length - offset;
|
||||
offset = last->fe_logical + last->fe_length;
|
||||
len -= xoffset;
|
||||
goto more;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -295,6 +295,8 @@ TEST_P(StoreTest, FiemapEmpty) {
|
||||
|
||||
TEST_P(StoreTest, FiemapHoles) {
|
||||
ObjectStore::Sequencer osr("test");
|
||||
const uint64_t MAX_EXTENTS = 4000;
|
||||
const uint64_t SKIP_STEP = 65536;
|
||||
coll_t cid;
|
||||
int r = 0;
|
||||
ghobject_t oid(hobject_t(sobject_t("fiemap_object", CEPH_NOSNAP)));
|
||||
@ -304,27 +306,28 @@ TEST_P(StoreTest, FiemapHoles) {
|
||||
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);
|
||||
for (uint64_t i = 0; i < MAX_EXTENTS; i++)
|
||||
t.write(cid, oid, SKIP_STEP * i, 3, bl);
|
||||
r = apply_transaction(store, &osr, std::move(t));
|
||||
ASSERT_EQ(r, 0);
|
||||
}
|
||||
{
|
||||
bufferlist bl;
|
||||
store->fiemap(cid, oid, 0, 4194307, bl);
|
||||
store->fiemap(cid, oid, 0, SKIP_STEP * (MAX_EXTENTS - 1) + 3, 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], 3u);
|
||||
bool extents_exist = true;
|
||||
if (m.size() == MAX_EXTENTS) {
|
||||
for (uint64_t i = 0; i < MAX_EXTENTS; i++)
|
||||
extents_exist = extents_exist && m.count(SKIP_STEP*i);
|
||||
}
|
||||
ASSERT_TRUE((m.size() == 1 &&
|
||||
m[0] > 4194304u) ||
|
||||
(m.size() == 3 &&
|
||||
m.count(0) &&
|
||||
m.count(1048576) &&
|
||||
m.count(4194304)));
|
||||
m[0] > SKIP_STEP * (MAX_EXTENTS - 1)) ||
|
||||
(m.size() == MAX_EXTENTS && extents_exist));
|
||||
}
|
||||
{
|
||||
ObjectStore::Transaction t;
|
||||
|
Loading…
Reference in New Issue
Block a user