summaryrefslogtreecommitdiffstats
path: root/drivers/md/persistent-data
diff options
context:
space:
mode:
authorJoe Thornber <ejt@redhat.com>2016-07-01 11:09:13 +0100
committerMike Snitzer <snitzer@redhat.com>2016-07-20 12:43:34 -0400
commite7e0f730477dea190fbc18c2d93338dacee82cea (patch)
treea32f1e357ed773559a8db6a9cf8315c4ae78cbd5 /drivers/md/persistent-data
parent89d3d9a1e38a6bd453038cfdc7e1576ef2d19719 (diff)
downloadlinux-stable-e7e0f730477dea190fbc18c2d93338dacee82cea.tar.gz
linux-stable-e7e0f730477dea190fbc18c2d93338dacee82cea.tar.bz2
linux-stable-e7e0f730477dea190fbc18c2d93338dacee82cea.zip
dm btree: fix a bug in dm_btree_find_next_single()
dm_btree_find_next_single() can short-circuit the search for a block with a return of -ENODATA if all entries are higher than the search key passed to lower_bound(). This hasn't been a problem because of the way the btree has been used by DM thinp. But it must be fixed now in preparation for fixing the race in DM thinp's handling of simultaneous block discard vs allocation. Otherwise, once that fix is in place, some of the blocks in a discard would not be unmapped as expected. Signed-off-by: Joe Thornber <ejt@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'drivers/md/persistent-data')
-rw-r--r--drivers/md/persistent-data/dm-btree.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/drivers/md/persistent-data/dm-btree.c b/drivers/md/persistent-data/dm-btree.c
index ea3d3b656fd0..2cc1877804c2 100644
--- a/drivers/md/persistent-data/dm-btree.c
+++ b/drivers/md/persistent-data/dm-btree.c
@@ -429,7 +429,14 @@ static int dm_btree_lookup_next_single(struct dm_btree_info *info, dm_block_t ro
if (flags & INTERNAL_NODE) {
i = lower_bound(n, key);
- if (i < 0 || i >= nr_entries) {
+ if (i < 0) {
+ /*
+ * avoid early -ENODATA return when all entries are
+ * higher than the search @key.
+ */
+ i = 0;
+ }
+ if (i >= nr_entries) {
r = -ENODATA;
goto out;
}