if (data->nodes[data->nr])
io_put_rsrc_node(data->nodes[data->nr]);
}
+ data->last_node = NULL;
+ data->last_index = -1U;
kvfree(data->nodes);
data->nodes = NULL;
data->nr = 0;
GFP_KERNEL_ACCOUNT | __GFP_ZERO);
if (data->nodes) {
data->nr = nr;
+ data->last_index = -1U;
return 0;
}
return -ENOMEM;
static inline struct io_rsrc_node *io_rsrc_node_lookup(struct io_rsrc_data *data,
int index)
{
- if (index < data->nr)
- return data->nodes[array_index_nospec(index, data->nr)];
+ if (index < data->nr) {
+ if (index != data->last_index) {
+ index = array_index_nospec(index, data->nr);
+ if (data->nodes[index]) {
+ data->last_index = index;
+ data->last_node = data->nodes[index];
+ }
+ }
+ return data->last_node;
+ }
return NULL;
}
{
struct io_rsrc_node *node = data->nodes[index];
- if (!node)
+ if (!node) {
+ WARN_ON_ONCE(index == data->last_index);
return false;
+ }
+ if (index == data->last_index) {
+ data->last_node = NULL;
+ data->last_index = -1U;
+ }
io_put_rsrc_node(node);
data->nodes[index] = NULL;
return true;