summaryrefslogtreecommitdiff
path: root/drivers/md/persistent-data/dm-btree-internal.h
diff options
context:
space:
mode:
authorJoe Thornber <ejt@redhat.com>2014-11-10 18:03:24 +0300
committerMike Snitzer <snitzer@redhat.com>2014-11-10 23:23:58 +0300
commit9b460d3699324d570a4d4161c3741431887f102f (patch)
tree2349384b5bb988ddb1b9a1bca9b55c99d577dd71 /drivers/md/persistent-data/dm-btree-internal.h
parentc822ed967cba38505713d59ed40a114386ef6c01 (diff)
downloadlinux-9b460d3699324d570a4d4161c3741431887f102f.tar.xz
dm btree: fix a recursion depth bug in btree walking code
The walk code was using a 'ro_spine' to hold it's locked btree nodes. But this data structure is designed for the rolling lock scheme, and as such automatically unlocks blocks that are two steps up the call chain. This is not suitable for the simple recursive walk algorithm, which retraces its steps. This code is only used by the persistent array code, which in turn is only used by dm-cache. In order to trigger it you need to have a mapping tree that is more than 2 levels deep; which equates to 8-16 million cache blocks. For instance a 4T ssd with a very small block size of 32k only just triggers this bug. The fix just places the locked blocks on the stack, and stops using the ro_spine altogether. Signed-off-by: Joe Thornber <ejt@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com> Cc: stable@vger.kernel.org
Diffstat (limited to 'drivers/md/persistent-data/dm-btree-internal.h')
-rw-r--r--drivers/md/persistent-data/dm-btree-internal.h6
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/md/persistent-data/dm-btree-internal.h b/drivers/md/persistent-data/dm-btree-internal.h
index 37d367bb9aa8..bf2b80d5c470 100644
--- a/drivers/md/persistent-data/dm-btree-internal.h
+++ b/drivers/md/persistent-data/dm-btree-internal.h
@@ -42,6 +42,12 @@ struct btree_node {
} __packed;
+/*
+ * Locks a block using the btree node validator.
+ */
+int bn_read_lock(struct dm_btree_info *info, dm_block_t b,
+ struct dm_block **result);
+
void inc_children(struct dm_transaction_manager *tm, struct btree_node *n,
struct dm_btree_value_type *vt);