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>
return NULL;
if (node) {
- xas->xa_alloc = NULL;
+ xas->xa_alloc = rcu_dereference_raw(node->parent);
} else {
gfp_t gfp = GFP_NOWAIT | __GFP_NOWARN;