From 36f6b668a8910d76847674086cbc86910c78faee Mon Sep 17 00:00:00 2001 From: Ning Yao Date: Thu, 6 Apr 2017 11:12:04 +0000 Subject: [PATCH] os/filestore: fix infinit loops in fiemap() since fiemap can get extents based on offset --> len but we should consider last extents is retrieved when len == 0 even though it is not last fiemap extents Signed-off-by: Ning Yao --- src/os/filestore/FileStore.cc | 13 +++++-------- src/test/objectstore/store_test.cc | 21 +++++++++++++++++++++ 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/os/filestore/FileStore.cc b/src/os/filestore/FileStore.cc index b07b3b2f43d2a..5c408e343a44c 100644 --- a/src/os/filestore/FileStore.cc +++ b/src/os/filestore/FileStore.cc @@ -3249,17 +3249,14 @@ more: i++; last = extent++; } - const bool is_last = 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; + const bool is_last = (last->fe_flags & FIEMAP_EXTENT_LAST) || (len == 0); + free(fiemap); if (!is_last) { - uint64_t xoffset = last->fe_logical + last->fe_length - offset; - offset = last->fe_logical + last->fe_length; - len -= xoffset; - free(fiemap); /* fix clang warn: use-after-free */ goto more; } - else { - free(fiemap); - } return r; } diff --git a/src/test/objectstore/store_test.cc b/src/test/objectstore/store_test.cc index 2a69c72364cc5..d42f71b019170 100644 --- a/src/test/objectstore/store_test.cc +++ b/src/test/objectstore/store_test.cc @@ -451,6 +451,7 @@ TEST_P(StoreTest, FiemapHoles) { ASSERT_EQ(r, 0); } { + //fiemap test from 0 to SKIP_STEP * (MAX_EXTENTS - 1) + 3 bufferlist bl; store->fiemap(cid, oid, 0, SKIP_STEP * (MAX_EXTENTS - 1) + 3, bl); map m, e; @@ -467,6 +468,26 @@ TEST_P(StoreTest, FiemapHoles) { ASSERT_TRUE((m.size() == 1 && m[0] > SKIP_STEP * (MAX_EXTENTS - 1)) || (m.size() == MAX_EXTENTS && extents_exist)); + + // fiemap test from SKIP_STEP to SKIP_STEP * (MAX_EXTENTS - 2) + 3 + // reset bufferlist and map + bl.clear(); + m.clear(); + e.clear(); + store->fiemap(cid, oid, SKIP_STEP, SKIP_STEP * (MAX_EXTENTS - 2) + 3, bl); + p = bl.begin(); + ::decode(m, p); + cout << " got " << m << std::endl; + ASSERT_TRUE(!m.empty()); + ASSERT_GE(m[SKIP_STEP], 3u); + extents_exist = true; + if (m.size() == (MAX_EXTENTS - 2)) { + for (uint64_t i = 1; i < MAX_EXTENTS - 1; i++) + extents_exist = extents_exist && m.count(SKIP_STEP*i); + } + ASSERT_TRUE((m.size() == 1 && + m[SKIP_STEP] > SKIP_STEP * (MAX_EXTENTS - 2)) || + (m.size() == (MAX_EXTENTS - 1) && extents_exist)); } { ObjectStore::Transaction t; -- 2.39.5