Skip to content

Commit 4848361

Browse files
author
Matthew Wilcox
committed
XArray: Fix xa_alloc when id exceeds max
Specifying a starting ID greater than the maximum ID isn't something attempted very often, but it should fail. It was succeeding due to xas_find_marked() returning the wrong error state, so add tests for both xa_alloc() and xas_find_marked(). Fixes: b803b42 ("xarray: Add XArray iterators") Signed-off-by: Matthew Wilcox <willy@infradead.org>
1 parent 4f145cd commit 4848361

File tree

2 files changed

+36
-5
lines changed

2 files changed

+36
-5
lines changed

lib/test_xarray.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,15 @@ static noinline void check_xa_alloc(void)
633633
GFP_KERNEL) != -ENOSPC);
634634
XA_BUG_ON(&xa0, id != 0xffffffffU);
635635
xa_destroy(&xa0);
636+
637+
id = 10;
638+
XA_BUG_ON(&xa0, xa_alloc(&xa0, &id, 5, xa_mk_index(id),
639+
GFP_KERNEL) != -ENOSPC);
640+
XA_BUG_ON(&xa0, xa_store_index(&xa0, 3, GFP_KERNEL) != 0);
641+
XA_BUG_ON(&xa0, xa_alloc(&xa0, &id, 5, xa_mk_index(id),
642+
GFP_KERNEL) != -ENOSPC);
643+
xa_erase_index(&xa0, 3);
644+
XA_BUG_ON(&xa0, !xa_empty(&xa0));
636645
}
637646

638647
static noinline void __check_store_iter(struct xarray *xa, unsigned long start,
@@ -822,10 +831,34 @@ static noinline void check_find_2(struct xarray *xa)
822831
xa_destroy(xa);
823832
}
824833

834+
static noinline void check_find_3(struct xarray *xa)
835+
{
836+
XA_STATE(xas, xa, 0);
837+
unsigned long i, j, k;
838+
void *entry;
839+
840+
for (i = 0; i < 100; i++) {
841+
for (j = 0; j < 100; j++) {
842+
for (k = 0; k < 100; k++) {
843+
xas_set(&xas, j);
844+
xas_for_each_marked(&xas, entry, k, XA_MARK_0)
845+
;
846+
if (j > k)
847+
XA_BUG_ON(xa,
848+
xas.xa_node != XAS_RESTART);
849+
}
850+
}
851+
xa_store_index(xa, i, GFP_KERNEL);
852+
xa_set_mark(xa, i, XA_MARK_0);
853+
}
854+
xa_destroy(xa);
855+
}
856+
825857
static noinline void check_find(struct xarray *xa)
826858
{
827859
check_find_1(xa);
828860
check_find_2(xa);
861+
check_find_3(xa);
829862
check_multi_find(xa);
830863
check_multi_find_2(xa);
831864
}

lib/xarray.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,7 +1131,7 @@ void *xas_find_marked(struct xa_state *xas, unsigned long max, xa_mark_t mark)
11311131
entry = xa_head(xas->xa);
11321132
xas->xa_node = NULL;
11331133
if (xas->xa_index > max_index(entry))
1134-
goto bounds;
1134+
goto out;
11351135
if (!xa_is_node(entry)) {
11361136
if (xa_marked(xas->xa, mark))
11371137
return entry;
@@ -1180,11 +1180,9 @@ void *xas_find_marked(struct xa_state *xas, unsigned long max, xa_mark_t mark)
11801180
}
11811181

11821182
out:
1183-
if (!max)
1183+
if (xas->xa_index > max)
11841184
goto max;
1185-
bounds:
1186-
xas->xa_node = XAS_BOUNDS;
1187-
return NULL;
1185+
return set_bounds(xas);
11881186
max:
11891187
xas->xa_node = XAS_RESTART;
11901188
return NULL;

0 commit comments

Comments
 (0)