mirror of
https://github.com/versity/scoutfs.git
synced 2026-06-08 20:52:35 +00:00
735c2c6905ccb4ea8119d44ad4d1f33431c93e21
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>
Description
No description provided
Languages
C
86.2%
Shell
10.2%
Roff
2.5%
TeX
0.8%
Makefile
0.3%