Zach Brown 735c2c6905 scoutfs: fix btree split/join setting parent keys
Before the introduction of the AVL tree to sort btree items, the items
were sorted by sorting a small packed array of offsets.  The final
offset in that array pointed to the item in the block with the greatest
key.

With the move to sorting items in an AVL tree by nodes embedded in item
structs, we now don't have the array of offsets and instead have a dense
array of items.  Creation and deletion of items always works with the
final item in the array.

last_item() used to return the item with the greatest key by returning
the item pointed to by the final entry in the sorted offset array, then
it returned the final entry in the item array for creation and deletion
but that was no longer the item with the greatest key.

But spliting and joining still used last_item() to find the item in the
block with the greatest key for updating references to blocks in
parents.  Since the introduction of the AVL tree splitting and joining
has been corrrupting the tree by setting parent block reference keys to
whatever item happened to be at the end of the array, not the item with
the greatest key.

The extent code recently pushed hard enough to hit this by working with
relatively random extent items in the core allocation btrees.
Eventually the parent block reference keys got out of sync and we'd fail
to find items by descending into the wrong children when looking for
them.  Extent deletion hit this during allocation, returned -ENOENT, and
the allocator turned that into -ENOSPC.

With this fixed we can repetedly create and delte millions of files with
heavily fragmented extents in a tiny metadata device.  Eventually it
actually runs out of space instead of spuriously returning ENOSPC in a
matter of minutes.

Signed-off-by: Zach Brown <zab@versity.com>
2020-10-26 15:19:03 -07:00
Description
No description provided
9.1 MiB
Languages
C 86.2%
Shell 10.2%
Roff 2.5%
TeX 0.8%
Makefile 0.3%