Skip to content

Commit

Permalink
XArray: Fix xa_alloc when id exceeds max
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
Matthew Wilcox committed Dec 13, 2018
1 parent 4f145cd commit 4848361
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 5 deletions.
33 changes: 33 additions & 0 deletions lib/test_xarray.c
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,15 @@ static noinline void check_xa_alloc(void)
GFP_KERNEL) != -ENOSPC);
XA_BUG_ON(&xa0, id != 0xffffffffU);
xa_destroy(&xa0);

id = 10;
XA_BUG_ON(&xa0, xa_alloc(&xa0, &id, 5, xa_mk_index(id),
GFP_KERNEL) != -ENOSPC);
XA_BUG_ON(&xa0, xa_store_index(&xa0, 3, GFP_KERNEL) != 0);
XA_BUG_ON(&xa0, xa_alloc(&xa0, &id, 5, xa_mk_index(id),
GFP_KERNEL) != -ENOSPC);
xa_erase_index(&xa0, 3);
XA_BUG_ON(&xa0, !xa_empty(&xa0));
}

static noinline void __check_store_iter(struct xarray *xa, unsigned long start,
Expand Down Expand Up @@ -822,10 +831,34 @@ static noinline void check_find_2(struct xarray *xa)
xa_destroy(xa);
}

static noinline void check_find_3(struct xarray *xa)
{
XA_STATE(xas, xa, 0);
unsigned long i, j, k;
void *entry;

for (i = 0; i < 100; i++) {
for (j = 0; j < 100; j++) {
for (k = 0; k < 100; k++) {
xas_set(&xas, j);
xas_for_each_marked(&xas, entry, k, XA_MARK_0)
;
if (j > k)
XA_BUG_ON(xa,
xas.xa_node != XAS_RESTART);
}
}
xa_store_index(xa, i, GFP_KERNEL);
xa_set_mark(xa, i, XA_MARK_0);
}
xa_destroy(xa);
}

static noinline void check_find(struct xarray *xa)
{
check_find_1(xa);
check_find_2(xa);
check_find_3(xa);
check_multi_find(xa);
check_multi_find_2(xa);
}
Expand Down
8 changes: 3 additions & 5 deletions lib/xarray.c
Original file line number Diff line number Diff line change
Expand Up @@ -1131,7 +1131,7 @@ void *xas_find_marked(struct xa_state *xas, unsigned long max, xa_mark_t mark)
entry = xa_head(xas->xa);
xas->xa_node = NULL;
if (xas->xa_index > max_index(entry))
goto bounds;
goto out;
if (!xa_is_node(entry)) {
if (xa_marked(xas->xa, mark))
return entry;
Expand Down Expand Up @@ -1180,11 +1180,9 @@ void *xas_find_marked(struct xa_state *xas, unsigned long max, xa_mark_t mark)
}

out:
if (!max)
if (xas->xa_index > max)
goto max;
bounds:
xas->xa_node = XAS_BOUNDS;
return NULL;
return set_bounds(xas);
max:
xas->xa_node = XAS_RESTART;
return NULL;
Expand Down

0 comments on commit 4848361

Please sign in to comment.