summaryrefslogtreecommitdiff
path: root/include/linux/xarray.h
diff options
context:
space:
mode:
authorMatthew Wilcox (Oracle) <willy@infradead.org>2020-08-02 14:17:21 -0400
committerMatthew Wilcox (Oracle) <willy@infradead.org>2020-10-13 08:41:26 -0400
commitca7b639e8611b3260a30b18aaa0d6db9c80a75ef (patch)
tree2cbbfb3b1f50df40778a0d9d7c748aada857c743 /include/linux/xarray.h
parentf82cd2f0b5eb715b1a296e20b34da7d296b6e9a4 (diff)
XArray: Fix xas_reload for multi-index entries
xas_reload() was only checking that the head entry was still at the head index. If the entry has been split, that's not enough as there may be a different entry at the specified index now. Solve this by checking the slot for the requested index instead of the head index. Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Diffstat (limited to 'include/linux/xarray.h')
-rw-r--r--include/linux/xarray.h19
1 files changed, 15 insertions, 4 deletions
diff --git a/include/linux/xarray.h b/include/linux/xarray.h
index 29db4e16eb89..4be9c57132fe 100644
--- a/include/linux/xarray.h
+++ b/include/linux/xarray.h
@@ -1524,10 +1524,21 @@ void xas_create_range(struct xa_state *);
static inline void *xas_reload(struct xa_state *xas)
{
struct xa_node *node = xas->xa_node;
-
- if (node)
- return xa_entry(xas->xa, node, xas->xa_offset);
- return xa_head(xas->xa);
+ void *entry;
+ char offset;
+
+ if (!node)
+ return xa_head(xas->xa);
+ if (IS_ENABLED(CONFIG_XARRAY_MULTI)) {
+ offset = (xas->xa_index >> node->shift) & XA_CHUNK_MASK;
+ entry = xa_entry(xas->xa, node, offset);
+ if (!xa_is_sibling(entry))
+ return entry;
+ offset = xa_to_sibling(entry);
+ } else {
+ offset = xas->xa_offset;
+ }
+ return xa_entry(xas->xa, node, offset);
}
/**