diff options
Diffstat (limited to 'sys-cluster/ceph/files/ceph-10.2.9-filestore_fix_infinit_loops_in_fiemap.patch')
-rw-r--r-- | sys-cluster/ceph/files/ceph-10.2.9-filestore_fix_infinit_loops_in_fiemap.patch | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/sys-cluster/ceph/files/ceph-10.2.9-filestore_fix_infinit_loops_in_fiemap.patch b/sys-cluster/ceph/files/ceph-10.2.9-filestore_fix_infinit_loops_in_fiemap.patch new file mode 100644 index 000000000000..e67113e51cc8 --- /dev/null +++ b/sys-cluster/ceph/files/ceph-10.2.9-filestore_fix_infinit_loops_in_fiemap.patch @@ -0,0 +1,82 @@ +From b52bfe6b443f0ff88c8614441752102058063699 Mon Sep 17 00:00:00 2001 +From: Ning Yao <yaoning@unitedstack.com> +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 <yaoning@unitedstack.com> +(cherry picked from commit 36f6b668a8910d76847674086cbc86910c78faee) +--- + 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 c47b0d0d2eae..95f48cdf4960 100644 +--- a/src/os/filestore/FileStore.cc ++++ b/src/os/filestore/FileStore.cc +@@ -3102,17 +3102,14 @@ int FileStore::_do_fiemap(int fd, uint64_t offset, size_t len, + 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 5ab011ad17d8..4cada7e2e435 100644 +--- a/src/test/objectstore/store_test.cc ++++ b/src/test/objectstore/store_test.cc +@@ -279,6 +279,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<uint64_t,uint64_t> m, e; +@@ -295,6 +296,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; |