summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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.patch82
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;