linux/drivers/md/persistent-data
Joe Thornber bc68d0a435 dm btree: fix serious bug in btree_split_beneath()
When inserting a new key/value pair into a btree we walk down the spine of
btree nodes performing the following 2 operations:

  i) space for a new entry
  ii) adjusting the first key entry if the new key is lower than any in the node.

If the _root_ node is full, the function btree_split_beneath() allocates 2 new
nodes, and redistibutes the root nodes entries between them.  The root node is
left with 2 entries corresponding to the 2 new nodes.

btree_split_beneath() then adjusts the spine to point to one of the two new
children.  This means the first key is never adjusted if the new key was lower,
ie. operation (ii) gets missed out.  This can result in the new key being
'lost' for a period; until another low valued key is inserted that will uncover
it.

This is a serious bug, and quite hard to make trigger in normal use.  A
reproducing test case ("thin create devices-in-reverse-order") is
available as part of the thin-provision-tools project:
  https://github.com/jthornber/thin-provisioning-tools/blob/master/functional-tests/device-mapper/dm-tests.scm#L593

Fix the issue by changing btree_split_beneath() so it no longer adjusts
the spine.  Instead it unlocks both the new nodes, and lets the main
loop in btree_insert_raw() relock the appropriate one and make any
neccessary adjustments.

Cc: stable@vger.kernel.org
Reported-by: Monty Pavel <monty_pavel@sina.com>
Signed-off-by: Joe Thornber <thornber@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
2018-01-17 09:07:55 -05:00
..
dm-array.c dm persistent data: add cursor skip functions to the cursor APIs 2017-02-16 13:12:50 -05:00
dm-array.h dm persistent data: add cursor skip functions to the cursor APIs 2017-02-16 13:12:50 -05:00
dm-bitset.c dm persistent data: add cursor skip functions to the cursor APIs 2017-02-16 13:12:50 -05:00
dm-bitset.h dm persistent data: add cursor skip functions to the cursor APIs 2017-02-16 13:12:50 -05:00
dm-block-manager.c dm block manager: remove an unused argument from dm_block_manager_create() 2017-04-27 17:08:41 -04:00
dm-block-manager.h dm block manager: remove an unused argument from dm_block_manager_create() 2017-04-27 17:08:41 -04:00
dm-btree-internal.h dm persistent data: eliminate unnecessary return values 2015-10-31 19:06:02 -04:00
dm-btree-remove.c - Revert a dm-multipath change that caused a regression for unprivledged 2015-11-04 21:19:53 -08:00
dm-btree-spine.c dm persistent data: eliminate unnecessary return values 2015-10-31 19:06:02 -04:00
dm-btree.c dm btree: fix serious bug in btree_split_beneath() 2018-01-17 09:07:55 -05:00
dm-btree.h dm persistent data: add cursor skip functions to the cursor APIs 2017-02-16 13:12:50 -05:00
dm-persistent-data-internal.h
dm-space-map-common.c dm space map common: memcpy the disk root to ensure it's arch aligned 2017-02-16 13:02:54 -05:00
dm-space-map-common.h
dm-space-map-disk.c dm space map disk: fix some book keeping in the disk space map 2017-05-15 15:09:50 -04:00
dm-space-map-disk.h
dm-space-map-metadata.c dm space map metadata: use ARRAY_SIZE 2017-11-10 15:44:52 -05:00
dm-space-map-metadata.h dm thin: allow metadata space larger than supported to go unused 2014-02-27 11:49:08 -05:00
dm-space-map.h dm persistent data: add threshold callback to space map 2013-05-10 14:37:20 +01:00
dm-transaction-manager.c dm persistent data: eliminate unnecessary return values 2015-10-31 19:06:02 -04:00
dm-transaction-manager.h dm persistent data: eliminate unnecessary return values 2015-10-31 19:06:02 -04:00
Kconfig dm bufio: store stacktrace in buffers to help find buffer leaks 2015-12-10 10:38:58 -05:00
Makefile License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00