XArray: Prevent node leaks in xas_alloc()

In the following situation, we can leak nodes:

do {
	xas_split_alloc();
	xas_lock();
	/* Discover that xas_split() does not need to be called */
	xas_store();
	xas_unlock();
} while (xas_nomem());

The xas_store() is expecting to be using a node allocated by xas_alloc(),
but will use a node allocated by xas_split_alloc() instead.  That
will cause us to leak the remaining nodes which are chained through
node->parent.  Fix this by only popping the top node off the xa_alloc
list instead of removing all the nodes.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
This commit is contained in:
Matthew Wilcox (Oracle) 2024-09-23 14:33:40 -04:00
parent f8eb5bd9a8
commit c88414f56c

View File

@ -366,7 +366,7 @@ static void *xas_alloc(struct xa_state *xas, unsigned int shift)
return NULL;
if (node) {
xas->xa_alloc = NULL;
xas->xa_alloc = rcu_dereference_raw(node->parent);
} else {
gfp_t gfp = GFP_NOWAIT | __GFP_NOWARN;